# Install - Debian Flavors Ubuntu, Mint [Reference](http://ryanbigg.com/2010/12/ubuntu-ruby-rvm-rails-and-you/) ```bash $ sudo apt-get -y install build-essential git-core curl $ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) echo 'source .rvm/scripts/rvm' >> ~/.bashrc; source ~/.bashrc $ sudo apt-get install -y --force-yes build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion $ rvm install 1.9.2; rvm use 1.9.2; rvm --default use 1.9.2 ``` ## Debugger on Emacs [ref](http://pivotallabs.com/users/chad/blog/articles/366-ruby-debug-in-30-seconds-we-don-t-need-no-stinkin-gui-) For ruby 1.9 do: $ gem install ruby-debug19 ruby-debug-ide get latest ruby-debug-extra from: * http://rubyforge.org/projects/ruby-debug/ > files this needs texlive do (it takes a looooong time to install), also get the rdebug cheat sheet: ```bash $ sudo apt-get install texlive texinfo $ cd Downloads; wget http://rubyforge.org/frs/download.php/73086/ruby-debug-extra-0.10.4.tar.gz; tar xvfz ruby-debug-extra-0.10.4.tar.gz; cd ruby-debug-extra-0.10.4/; ./configure; make; sudo make install $ gem install cheat; cheat rdebug ``` create a file ~/.rdebugrc with this content: ``` set autolist set autoeval set autoreload ``` * autolist - execute 'list' command on every breakpoint * autoeval - evaluate every unrecognized command * autoreload - enables automatic source code reloading **IMPORTANT**: open emacs from shell to inherit all environment from shell!!! Open your ruby file and type: `M-x rdebug` Key | Effect -------------------------------------- | --------------------- r | Reload n | Next Line (Step Over) s | Step Into c | Continue c[ont][ nnn] | run until program ends or hits breakpoint or reaches line nnn where | Display Frame / Call Stack b my.rb:10 | set breakpoint at my.rb line 10 b[reak] file:line [if expr] | breakpoints b[reak] class(.|#)method [if expr] | breakpoints h | help @myvar = 'foo' | Modify a variable myvar.class | Evaluate any var/expression disp[lay] | add expression into display expression list down [count] | move to lower frame e[val] | expression evaluate expression and print its value, alias for p q[uit], exit | fin[ish] | return to outer frame m[ethod] i[nstance] | show methods of object m[ethod] | show instance methods of class or module n[ext][+][ nnn] | step over once or nnn times, '+' forces to move to another line up[count] | move to higher frame restart | restart the debugger (say if in (rdb:ctrl) state. # Language Reference ## Define a method ```ruby irb(main):019:0> def h(name = "World") irb(main):020:1> puts "Hello #{name.capitalize}!" irb(main):021:1> end => nil irb(main):022:0> h "chris" Hello Chris! => nil irb(main):023:0> h Hello World! => nil ``` Highlights: * default parameter value: "World", if method called without a param. * `#{}` is string interpolation ## Modules define a module file: `fenton.rb` ```ruby module MyModule def func1 puts "Hello" end end ``` ### Mixin Modules cannot be instantiated, only included into a class. This is called a `mixin`. In file `travers.rb`. Modules can include other modules. ```ruby require 'fenton' class ClassOne include MyModule def func2 func1 end end ``` ### Sharing Code required statement should be following by path and filenames I may define the following in file: `lib/myTools/fenton.rb` ```ruby module ItTools class VpnTools def on_vpn puts "hello." end end end ``` Assuming lib is one of the number of pre-defined directories on your system. These paths are defined in a variable called `$LOAD_PATH` To use this in another file I'd do: ```ruby require 'myTools/fenton' foo = ItTools::VpnTools.new foo.on_vpn ``` ## Exception Handling ```ruby begin 1/0 p 'I should never get executed' rescue p 'I am rescuing an exception and can do what I want!' end ``` ## Inheritance [ref](http://rubylearning.com/satishtalim/ruby_inheritance.html) * A class can only inherit from a *SINGLE* other class. ```ruby class Mammal def breathe puts "inhale and exhale" end end class Cat < Mammal def speak puts "Meow" end end rani = Cat.new rani.breathe rani.speak ``` ## Command Line Arguments are stored in the array `ARGV` ```ruby #!/usr/bin/env ruby ARGV.each do|a| puts "Argument: #{a}" end ``` # Cook Book ## Creating Gems [Ref](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html) In this example we create a gem called: `fentonGem1` ```bash $ rvm gemset create fentonGem1 $ rvm gemset use fentonGem1 $ gem install bundler $ bundle gem fentonGem1 ``` Look at `fentonGem1.gemspec` update summary/description lines: ```ruby s.summary = %q{Gem basically does nothing} s.description = %q{Gem really doesnt do anything} ``` ### Create our library function in file: `lib/fentonGem1/do_little.rb ```ruby module FentonGem1 class DoLittle def simpleFunc time = Time.now minute = time.min hour = time.hour % 12 meridian_indicator = time.hour < 12 ? 'AM' : 'PM' "#{minute} minutes past #{hour} o'clock, #{meridian_indicator}" end end end ``` ### Make it scriptable in file: `bin/getTimeNow` ```ruby #!/usr/bin/env ruby require 'fentonGem1/do_little' do_little = FentonGem1::DoLittle.new puts do_little.simpleFunc ``` ### Build Gem and Test Add items into git repository ```bash $ git add bin/ lib/*; git commit -am'.' ``` ```bash ~/tmp/fentonGem1$ rake install ~/tmp/fentonGem1$ getTimeNow ``` ### Publish Signup at rubygems.org: [Instructions at rubygems.org](https://rubygems.org/pages/gem_docs) publish with: ```bash $ gem push pkg/fentonGem1-0.0.1.gem ``` # Install - RedHat variants As root ```bash # yum install -y curl openssl-devel zlib-devel gcc gcc-c++ make autoconf readline-devel curl-devel expat-devel gettext-devel ``` As the user who will be using ruby: ```bash $ wget https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer $ chmod a+x rvm-installer $ echo insecure >> ~/.curlrc $ ./rvm-installer $ source /home/fenton/.bash_profile $ rvm install 1.9.3 $ echo -e "\nrvm use 1.9.3" >> ~/.bash_profile ``` Log out completely (so .bash_profile gets executed) and log back in. ```bash $ ruby --version ruby 1.9.3p0 (2011-10-30 revision 33570) [i686-linux] ``` # Unit Testing [ref](http://www.moseshohman.com/blog/2004/10/13/building-testunit-testsuites-in-ruby/) ## Test Case Folder layout: ``` it_tools/ ├── Gemfile ├── it_tools.gemspec ├── lib │ └── it_tools │ ├── deploy.rb │ ├── it_tools.rb │ ├── mail.rb │ └── version.rb ├── Rakefile └── test └── it_tools └── test_deploy.rb ``` Sample test: `test/it_tools/test_deploy.rb` ```ruby require "test/unit" require 'pathname' libpath = Pathname.new( File.join(File.dirname(__FILE__), [".."]*2, "lib") ).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require "it_tools/deploy" class TestEnvironment < Test::Unit::TestCase def test_get_deploy_dir env = Deployment::Environment.new assert_equal('/scratch/ngsp/hrmsToCrmod', env.get_deploy_dir('dev')) end end ``` This stuff: ```ruby require 'pathname' libpath = Pathname.new( File.join(File.dirname(__FILE__), [".."]*2, "lib") ).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) ``` ensures that `lib` is on your load path, so you can test now with: ```bash ~/projects/it_tools $ ruby test/it_tools/test_deploy.rb ``` ## Test Suite Layout: ``` it_tools/ ├── Gemfile ├── it_tools.gemspec ├── lib │ └── it_tools │ ├── deploy.rb │ ├── it_tools.rb │ ├── mail.rb │ └── version.rb ├── Rakefile └── test └── it_tools ├── suite_it_tools.rb └── test_deploy.rb ``` file: `test/it_tools/suite_it_tools.rb ```ruby require 'pathname' testpath = Pathname.new( File.join(File.dirname(__FILE__), ".."*1) ).cleanpath.to_s $:.unshift(testpath) unless $:.include?(testpath) require 'it_tools/test_deploy' te = TestDeployment::TestEnvironment.new("TestEnvironment") te.test_get_deploy_dir ``` test with: ```bash ~/projects/it_tools $ ruby test/it_tools/suite_it_tools.rb ```