Ruby ihower@gmail.com http://creativecommons.org/licenses/by-nc/2.5/tw/
? a.k.a. ihower http://ihower.idv.tw/blog/ twitter: ihower 2006 Ruby ( ) Rails Developer http://handlino.com http://registrano.com
Ruby? (interpreted) Yukihiro Matsumoto, a.k.a. Matz Lisp, Perl, Smalltalk Happy
irb: Interactive Ruby irb(main):001:0> irb(main):001:0> 1 + 1 => 2 irb(main):002:0>
Ruby Dynamic v.s. Static typing Ruby/Perl/Python/PHP v.s. Java/C/C++ Strong v.s. Weak typing Ruby/Perl/Python/Java v.s. PHP/C/C++
?? PHP code: Ruby code: $i = 1; echo "Value is " + $i # 1 C code: i=1 puts "Value is " + i #TypeError: can't convert Fixnum into String # from (irb):2:in `+' # from (irb):2 int a = 5; float b = a;
Ruby # "UPPER" puts "upper".upcase # -5 puts -5.abs # Fixnum puts 99.class # "Ruby Rocks!" 5.times do puts "Ruby Rocks!"
Array a = [ 1, "cat", 3.14 ] puts a[0] # 1 puts a.size # 3 a[2] = nil puts a.inspect # [1, "cat", nil]
Hash (Associative Array) config = { "foo" => 123, "bar" => 456 } puts config["foo"] # 123
Symbols config = { :foo => 123, :bar => 456 } puts config[:foo] # 123
If if account.total > 100000 puts "large account" elsif account.total > 25000 puts "medium account" else puts "small account"
If Perl Style if account.total > 100000 puts "large account" elsif account.total > 25000 puts "medium account" else puts "small account"
expression? true_expresion : false_expression x = 3 puts ( x > 3 )? " " : " " #
Case case name when "John" puts "Howdy John!" when "Ryan" puts "Whatz up Ryan!" else puts "Hi #{name}!"
while, loop, until, next and break i=0 while ( i < 10 ) i += 1 next if i % 2 == 0 # i = 0 loop do i += 1 break if i > 10 # i = 0 i += 1 until i > 10 puts i # 11
false nil puts "not execute" if nil puts "not execute" if false puts "execute" if true # execute puts "execute" if # execute ( JavaScript ) puts "execute" if 0 # execute ( C ) puts "execute" if 1 # execute puts "execute" if "foo" # execute puts "execute" if Array.new # execute
Regular Expressions Perl # phone = "123-456-7890" if phone =~ /(\d{3})-(\d{3})-(\d{4})/ ext = $1 city = $2 num = $3
Methods def def say_hello(name) result = "Hi, " + name return result puts say_hello('ihower') # Hi, ihower
Methods def def say_hello(name) result = "Hi, " + name return result puts say_hello('ihower') # Hi, ihower
Class class Greeter def initialize(name) @name = name def say(word) puts "#{word}, #{@name}" g1 = Greeter.new("ihower") g2 = Greeter.new("ihover") g1.say("hello") # Hello, ihower g2.say("hello") # Hello, ihover
Class class Greeter def initialize(name) @name = name def say(word) puts "#{word}, #{@name}" g1 = Greeter.new("ihower") g2 = Greeter.new("ihover") g1.say("hello") # Hello, ihower g2.say("hello") # Hello, ihover
Class class Greeter def initialize(name) @name = name def say(word) puts "#{word}, #{@name}" g1 = Greeter.new("ihower") g2 = Greeter.new("ihover") g1.say("hello") # Hello, ihower g2.say("hello") # Hello, ihover
Class class Greeter def initialize(name) @name = name def say(word) puts "#{word}, #{@name}" g1 = Greeter.new("ihower") g2 = Greeter.new("ihover") g1.say("hello") # Hello, ihower g2.say("hello") # Hello, ihover
Class class Greeter def initialize(name) @name = name def say(word) puts "#{word}, #{@name}" g1 = Greeter.new("ihower") g2 = Greeter.new("ihover") g1.say("hello") # Hello, ihower g2.say("hello") # Hello, ihover
Class ( ) class Greeter @@name = ihower def self.say puts @@name Greeter.say # Hello, ihower
Class ( ) class Greeter @@name = ihower def self.say puts @@name Greeter.say # Hello, ihower
Class ( ) class Greeter @@name = ihower def self.say puts @@name Greeter.say # Hello, ihower
Class body attr_accessor, attr_writer, attr_reader class Person class Person attr_accessor :name def name @name def name=(val) @name = val
class MyClass def public_method private def private_method protected def protected_method class MyClass def public_method def private_method def protected_method public :public_method private :private_method protected :proected_method
Class class Pet attr_accessor :name, :age class Cat < Pet class Dog < Pet
code block closure { puts "Hello" } # block do puts "Blah" # block puts "Blah"
code block (iterator) # people = ["David", "John", "Mary"] people.each do person puts person # 5.times { puts "Ruby rocks!" } # 1.upto(9) { x puts x }
code block (iterator) # people = ["David", "John", "Mary"] people.each do person puts person # 5.times { puts "Ruby rocks!" } # 1.upto(9) { x puts x } while, until, for
code block # a = [ "a", "b", "c", "d" ] b = a.map { x x + "!" } puts b.inspect # ["a!", "b!", "c!", "d!"] # b = [1,2,3].find_all{ x x % 2 == 0 } b.inspect # [2]
code block # a = [ "a", "b", "c" ] a.delete_if { x x >= "b" } # ["a"] # [2,1,3].sort! { a, b b <=> a } # ["3", 2, 1 ]
code block functional programming fu? # (5..10).inject { sum, n sum + n } # find the longest word longest = ["cat", "sheep", "bear"].inject do memo, word ( memo.length > word.length )? memo : word
code block file = File.new("testfile", "r") #... file.close File.open("testfile", "r") do file #... #
Yield yield code block # def call_block puts "Start" yield yield puts "End" call_block { puts "Blocks are cool!" } # # "Start" # "Blocks are cool!" # "Blocks are cool!" # "End"
code block def call_block yield(1) yield(2) yield(3) call_block { i puts "#{i}: Blocks are cool!" } # # "1: Blocks are cool!" # "2: Blocks are cool!" # "3: Blocks are cool!"
Proc object code block def call_block(&block) block.call(1) block.call(2) block.call(3) call_block { i puts "#{i}: Blocks are cool!" } # proc object proc_1 = Proc.new { i puts "#{i}: Blocks are cool!" } proc_2 = lambda { i puts "#{i}: Blocks are cool!" } call_block(&proc_1) call_block(&proc_2) # # "1: Blocks are cool!" # "2: Blocks are cool!" # "3: Blocks are cool!"
def my_sum(*val) val.inject(0) { sum, v sum + v } puts my_sum(1,2,3,4) # 10
Hash { } def my_print(a, b, options) puts a puts b puts options[:x] puts options[:y] puts options[:z] puts my_print("a", "B", { :x => 123, :z => 456 } ) puts my_print("a", "B", :x => 123, :z => 456) # # A # B # 123 # nil # 456
raise, begin, rescue, ensure raise "Not works!!" # RuntimeError # class MyException < RuntimeError raise MyException begin puts 10 / 0 rescue => e puts e.class ensure #... # ZeroDivisionError
Module (1) Namespace module MyUtil def self.foobar puts "foobar" MyUtil.foobar # foobar
Module(2) Mixins module Debug def who_am_i? "#{self.class.name} (\##{self.object_id}): #{self.to_s}" class Foo include Debug # Mixin #... class Bar include Debug include AwesomeModule #... ph = Foo.new("12312312") et = Bar.new("78678678") ph.who_am_i? # "Foo (#330450): 12312312" et.who_am_i? # "Bar (#330420): 78678678"
Module(2) Mixins module Debug def who_am_i? "#{self.class.name} (\##{self.object_id}): #{self.to_s}" class Foo include Debug # Mixin #... class Bar include Debug include AwesomeModule #... ph = Foo.new("12312312") et = Bar.new("78678678") Ruby Module ph.who_am_i? # "Foo (#330450): 12312312" et.who_am_i? # "Bar (#330420): 78678678"
(duck typing) # class Duck def quack puts "quack!" # ( ) class Mallard def quack puts "qwuaacck!! quak!"
Class Type birds = [Duck.new, Mallard.new, Object.new] # birds.each do duck duck.quack if duck.respond_to? :quack
Class Type birds = [Duck.new, Mallard.new, Object.new] # birds.each do duck duck.quack if duck.respond_to? :quack OOP!
Metaprogramming
define_method class Dragon define_method(:foo) { puts "bar" } ['a','b','c','d','e','f'].each do x define_method(x) { puts x } dragon = Dragon.new dragon.foo # "bar" dragon.a # "a" dragon.f # "f"
Domain-Specific Language class Firm < ActiveRecord::Base has_many :clients has_one :account belongs_to :conglomorate # has_many AciveRecord class method Firm instance methods firm = Firm.find(1) firm.clients firm.clients.size firm.clients.build firm.clients.destroy_all
Method Missing class Proxy def initialize(object) @object = object def method_missing(symbol, *args) @object.s(symbol, *args) object = ["a", "b", "c"] proxy = Proxy.new(object) puts proxy.first # Proxy first method_missing "a"
Introspection ( ) # Object.methods => ["s", "name", "class_eval", "object_id", "new", "singleton_methods",...] # Object.respond_to? :name => true
Ruby
Ruby production Ruby 1.8.6, 1.8.7 ( MRI, Matz Ruby Interpreter) Ruby 1.9.1 (YARV) JRuby Ruby1.8.6 1.9 Ruby Enterprise Edition(REE) Ruby 1.8.6 GC memory leak
Ruby production IronRuby (based on Microsoft.NET) MacRuby (based on Objective-C) Rubinius (Engine yard project) MagLev (based on smalltalk) Cardinal (based on Parrot VM)
Thank you. Beginning Ruby 2nd. (Apress) Programming Ruby (The Pragmatic Programmers) The Well-Grounded Rubyist (Manning) Ruby (O Reilly)