SlideShare a Scribd company logo
Advanced Ruby Beyond the Basics
Blocks {   puts   'Hello'   } do puts   'Hello' end
Blocks def   call_block   puts   'Start of method'   # you can call the block using the yield keyword  yield   yield   puts   'End of method'   end   # invoke call_block   {puts   'In the block' }   >> Start of method In the block In the block End of method
Blocks def   call_block_with_params puts   'Start of method'   yield   'foo' ,   'bar' puts   'End of method'   end # invoke call_block_with_params {|a,b|   puts   "#{a} #{b}" } >> Start of method foo bar End of method
Exercise 1 For the class ‘Exercise1’ Implement method ‘greet’ to: Accept an array of names and a block That joins all the names together with ‘and’ Implement method ‘invoke’ to: Call the ‘greet’ method, passing it the names ‘joe’ and ‘fred’ And pass greet a block that adds “Hello” in front of the names returned from ‘greet’ Should return “Hello joe and fred”
Proc objects p   =   Proc.new   {   puts   "Hello"   } p .call l   =   lambda   {   puts   "Hello"   } l .call
Proc vs lambda def   return_test l   =   lambda   {   return   } l .call puts   "Still here!" p   =   Proc.new   {   return   } p .call puts   "You won't see this." end return_test >> Still here!
Convert Blocks to Proc objects def   grab_block (&block) block .call end grab_block   {puts   "Hello" }
Higher Order Functions proc   =   lambda{puts   'Hello' } proc .call def   hello (proc) puts   "start of method" proc .call puts   "end of method" end # invoke hello   proc >> Hello >> start of method Hello end of method
Closures >> a = 1 @a = 2 original class   Holder def   call_block (pr) a   =   101 @a   =   102 pr .call end end class   Creator def   create_block a   =   1 @a   =   2 lambda   do puts   "a = #{a}" puts   "@a = #@a" puts   yield end end end block   =   Creator.new.create_block   {   "original"   } Holder .new.call_block   block
Metaprogramming Add/remove classes dynamically Add/remove methods dynamically Change existing methods Intercept messages to objects Useful for DSLs
Adding methods to a class class   Object def   greet puts   "Hello"   end end obj   =   Object.new obj .greet >> Hello obj2   =   Object.new obj2 .greet >> Hello
Adding methods to a class - example 3.hours .from_now class   Fixnum def   hours self   *   60   *   60 end def   from_now Time .now   +   self end end
Adding a method to an object obj   =   Object.new def   obj .greet puts   &quot;Hello&quot;   end obj .greet >> Hello obj2   =   Object.new obj2 .greet >> undefined method `greet' for #<Object:0x2bae594>
Singleton Class object Singleton class class module
Adding methods to singleton class s   =   &quot;Hello&quot; class   <<   s def   twice self   +   &quot; &quot;   +   self end end puts   s .twice >> Hello Hello def   s .twice self   +   &quot; &quot;   +   self end
Using modules module M def greet puts &quot;Hello&quot; end end obj = C.new class << obj include M end obj.greet obj = C.new obj.extend(M) obj.greet
Class method definitions class   String class   <<   self def   hello &quot;hello&quot; end end end class   <<   String def   hello &quot;hello&quot; end end def   String def   self .hello &quot;hello&quot; end end
Class methods and inheritance class C singleton class of C class D singleton class of D extends lookup path object
Exercise 2 Add a method to the already existing class ‘Account’ Create file ‘account_transfer_to.rb’ and “re-open” the Account class. To run the specs: spec .
Exercise 3 Add a method to an instance of a class Edit the file ‘account_instance_transfer_to_spec.rb’ Implement the ‘transfer_to’ method here, for account1 only.
Method Aliasing class   C def   hi puts   &quot;hello&quot; end end class   C alias_method   :original_hi ,   :hi def   hi puts   &quot;greetings“ original_hi end end obj   =   C.new obj .hi >> greetings hello
Exercise 4 Alias an existing method implement the ‘number_of_withdrawals’ and ‘number_of_deposits’ methods in a new file: ‘account_auditing.rb’ Reopen Account class and define @number_of_withdrawals and @number_of_deposits Alias original withdraw, deposit and initialize methods, and implement new versions.
Method_missing class   Echo def   method_missing   method_sym,   *args puts   &quot;#{method_sym}: #{args.inspect}&quot; end end Echo .new.yell   &quot;Hello&quot; ,   &quot;world!&quot; Echo .new.say   &quot;Good&quot; ,   &quot;bye!&quot; >> yell: [&quot;Hello&quot;, &quot;world!&quot;] say: [&quot;Good&quot;, &quot;bye!&quot;]
Exercise 5 Using method_missing Implement Remember class from scratch Remember class should accept any method, and store the method and any parameters in a history array
Dynamically add methods >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
Dynamically add methods class   Echo def   method_missing   method_sym,   *args p   &quot;defining method #{method_sym}&quot; self .class.class_eval   <<-EOF def   #{method_sym.to_s} *args p   &quot;#{method_sym}: &quot;   +   args.inspect end EOF send (method_sym,   *args) end end Echo .new.yell   &quot;Hello&quot; ,   &quot;world!&quot; Echo .new.yell   &quot;good&quot; ,   &quot;bye&quot; >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
Dynamically add methods class   Echo def   method_missing   method_sym,   *args p   &quot;defining method #{method_sym}&quot; Echo .class_eval   <<-EOF def   #{method_sym.to_s} *args p   &quot;#{method_sym}: &quot;   +   args.inspect end EOF send (method_sym,   *args) end end Echo .new.yell   &quot;Hello&quot; ,   &quot;world!&quot; Echo .new.yell   &quot;good&quot; ,   &quot;bye&quot; >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
Dynamically add instance methods >> &quot;new_method: [\&quot;blah\&quot;]&quot;
Dynamically add instance methods >> &quot;new_method: [\&quot;blah\&quot;]&quot;
Exercise 6 Dynamically add methods to a class at runtime Use method_missing the first time a method is called, but define the missing method on the class Subsequent calls to that method then won’t have to use method_missing.
Further Reading Ruby for Rails  book (ch13) –  David A. Black Seeing Metaclasses Clearly Dwemthy’s Array Ruby metaprogramming techniques
The End
Extra Stuff Continuations Symbols
Continuations def   strange callcc   {|continuation|   return   continuation} print   &quot;Back in method. &quot; end print   &quot;Before method. &quot; continuation   =   strange() print   &quot;After method. &quot; continuation .call   if   continuation Before method. After method. Back in method. After method. RETURN THIS
Symbols :this_is_a_symbol :’This is also a symbol’ Has both integer and string representations Is immutable Quicker to lookup than strings Quicker to compare No need to construct a string literal when doing lookups

More Related Content

PPT
Practical Ext JS Debugging
PPTX
Post Sharp Talk
KEY
Debugging Your Ext JS Code
PPTX
Ruby Blocks
PPT
Advanced PHPUnit Testing
PDF
PHPUnit best practices presentation
ODP
Dependency Injection
PPT
Php Debugger
Practical Ext JS Debugging
Post Sharp Talk
Debugging Your Ext JS Code
Ruby Blocks
Advanced PHPUnit Testing
PHPUnit best practices presentation
Dependency Injection
Php Debugger

Similar to Advanced Ruby (20)

PDF
Ruby 程式語言簡介
PPT
Metaprogramming With Ruby
PPT
Functional techniques in Ruby
PPT
Functional techniques in Ruby
PPT
Ruby For Java Programmers
PDF
Rapid Development with Ruby/JRuby and Rails
PDF
Ruby Topic Maps Tutorial (2007-10-10)
PPT
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
PDF
Designing Ruby APIs
PDF
A limited guide to intermediate and advanced Ruby
KEY
PDF
Steady with ruby
PPT
name name2 n2.ppt
PPT
name name2 n
PPT
name name2 n2
PPT
name name2 n
PPT
ppt18
PPT
ppt9
PPT
ppt7
PPT
ppt30
Ruby 程式語言簡介
Metaprogramming With Ruby
Functional techniques in Ruby
Functional techniques in Ruby
Ruby For Java Programmers
Rapid Development with Ruby/JRuby and Rails
Ruby Topic Maps Tutorial (2007-10-10)
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Designing Ruby APIs
A limited guide to intermediate and advanced Ruby
Steady with ruby
name name2 n2.ppt
name name2 n
name name2 n2
name name2 n
ppt18
ppt9
ppt7
ppt30
Ad

Recently uploaded (20)

PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Encapsulation theory and applications.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
KodekX | Application Modernization Development
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Spectroscopy.pptx food analysis technology
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Machine learning based COVID-19 study performance prediction
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Network Security Unit 5.pdf for BCA BBA.
Empathic Computing: Creating Shared Understanding
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Programs and apps: productivity, graphics, security and other tools
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
The Rise and Fall of 3GPP – Time for a Sabbatical?
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Encapsulation theory and applications.pdf
Big Data Technologies - Introduction.pptx
KodekX | Application Modernization Development
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Spectroscopy.pptx food analysis technology
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Machine learning based COVID-19 study performance prediction
sap open course for s4hana steps from ECC to s4
Building Integrated photovoltaic BIPV_UPV.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Ad

Advanced Ruby

  • 1. Advanced Ruby Beyond the Basics
  • 2. Blocks { puts 'Hello' } do puts 'Hello' end
  • 3. Blocks def call_block puts 'Start of method' # you can call the block using the yield keyword yield yield puts 'End of method' end # invoke call_block {puts 'In the block' } >> Start of method In the block In the block End of method
  • 4. Blocks def call_block_with_params puts 'Start of method' yield 'foo' , 'bar' puts 'End of method' end # invoke call_block_with_params {|a,b| puts &quot;#{a} #{b}&quot; } >> Start of method foo bar End of method
  • 5. Exercise 1 For the class ‘Exercise1’ Implement method ‘greet’ to: Accept an array of names and a block That joins all the names together with ‘and’ Implement method ‘invoke’ to: Call the ‘greet’ method, passing it the names ‘joe’ and ‘fred’ And pass greet a block that adds “Hello” in front of the names returned from ‘greet’ Should return “Hello joe and fred”
  • 6. Proc objects p = Proc.new { puts &quot;Hello&quot; } p .call l = lambda { puts &quot;Hello&quot; } l .call
  • 7. Proc vs lambda def return_test l = lambda { return } l .call puts &quot;Still here!&quot; p = Proc.new { return } p .call puts &quot;You won't see this.&quot; end return_test >> Still here!
  • 8. Convert Blocks to Proc objects def grab_block (&block) block .call end grab_block {puts &quot;Hello&quot; }
  • 9. Higher Order Functions proc = lambda{puts 'Hello' } proc .call def hello (proc) puts &quot;start of method&quot; proc .call puts &quot;end of method&quot; end # invoke hello proc >> Hello >> start of method Hello end of method
  • 10. Closures >> a = 1 @a = 2 original class Holder def call_block (pr) a = 101 @a = 102 pr .call end end class Creator def create_block a = 1 @a = 2 lambda do puts &quot;a = #{a}&quot; puts &quot;@a = #@a&quot; puts yield end end end block = Creator.new.create_block { &quot;original&quot; } Holder .new.call_block block
  • 11. Metaprogramming Add/remove classes dynamically Add/remove methods dynamically Change existing methods Intercept messages to objects Useful for DSLs
  • 12. Adding methods to a class class Object def greet puts &quot;Hello&quot; end end obj = Object.new obj .greet >> Hello obj2 = Object.new obj2 .greet >> Hello
  • 13. Adding methods to a class - example 3.hours .from_now class Fixnum def hours self * 60 * 60 end def from_now Time .now + self end end
  • 14. Adding a method to an object obj = Object.new def obj .greet puts &quot;Hello&quot; end obj .greet >> Hello obj2 = Object.new obj2 .greet >> undefined method `greet' for #<Object:0x2bae594>
  • 15. Singleton Class object Singleton class class module
  • 16. Adding methods to singleton class s = &quot;Hello&quot; class << s def twice self + &quot; &quot; + self end end puts s .twice >> Hello Hello def s .twice self + &quot; &quot; + self end
  • 17. Using modules module M def greet puts &quot;Hello&quot; end end obj = C.new class << obj include M end obj.greet obj = C.new obj.extend(M) obj.greet
  • 18. Class method definitions class String class << self def hello &quot;hello&quot; end end end class << String def hello &quot;hello&quot; end end def String def self .hello &quot;hello&quot; end end
  • 19. Class methods and inheritance class C singleton class of C class D singleton class of D extends lookup path object
  • 20. Exercise 2 Add a method to the already existing class ‘Account’ Create file ‘account_transfer_to.rb’ and “re-open” the Account class. To run the specs: spec .
  • 21. Exercise 3 Add a method to an instance of a class Edit the file ‘account_instance_transfer_to_spec.rb’ Implement the ‘transfer_to’ method here, for account1 only.
  • 22. Method Aliasing class C def hi puts &quot;hello&quot; end end class C alias_method :original_hi , :hi def hi puts &quot;greetings“ original_hi end end obj = C.new obj .hi >> greetings hello
  • 23. Exercise 4 Alias an existing method implement the ‘number_of_withdrawals’ and ‘number_of_deposits’ methods in a new file: ‘account_auditing.rb’ Reopen Account class and define @number_of_withdrawals and @number_of_deposits Alias original withdraw, deposit and initialize methods, and implement new versions.
  • 24. Method_missing class Echo def method_missing method_sym, *args puts &quot;#{method_sym}: #{args.inspect}&quot; end end Echo .new.yell &quot;Hello&quot; , &quot;world!&quot; Echo .new.say &quot;Good&quot; , &quot;bye!&quot; >> yell: [&quot;Hello&quot;, &quot;world!&quot;] say: [&quot;Good&quot;, &quot;bye!&quot;]
  • 25. Exercise 5 Using method_missing Implement Remember class from scratch Remember class should accept any method, and store the method and any parameters in a history array
  • 26. Dynamically add methods >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
  • 27. Dynamically add methods class Echo def method_missing method_sym, *args p &quot;defining method #{method_sym}&quot; self .class.class_eval <<-EOF def #{method_sym.to_s} *args p &quot;#{method_sym}: &quot; + args.inspect end EOF send (method_sym, *args) end end Echo .new.yell &quot;Hello&quot; , &quot;world!&quot; Echo .new.yell &quot;good&quot; , &quot;bye&quot; >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
  • 28. Dynamically add methods class Echo def method_missing method_sym, *args p &quot;defining method #{method_sym}&quot; Echo .class_eval <<-EOF def #{method_sym.to_s} *args p &quot;#{method_sym}: &quot; + args.inspect end EOF send (method_sym, *args) end end Echo .new.yell &quot;Hello&quot; , &quot;world!&quot; Echo .new.yell &quot;good&quot; , &quot;bye&quot; >> &quot;defining method yell“ &quot;yell: [\&quot;Hello\&quot;, \&quot;world!\&quot;]“ &quot;yell: [\&quot;good\&quot;, \&quot;bye\&quot;]&quot;
  • 29. Dynamically add instance methods >> &quot;new_method: [\&quot;blah\&quot;]&quot;
  • 30. Dynamically add instance methods >> &quot;new_method: [\&quot;blah\&quot;]&quot;
  • 31. Exercise 6 Dynamically add methods to a class at runtime Use method_missing the first time a method is called, but define the missing method on the class Subsequent calls to that method then won’t have to use method_missing.
  • 32. Further Reading Ruby for Rails book (ch13) – David A. Black Seeing Metaclasses Clearly Dwemthy’s Array Ruby metaprogramming techniques
  • 35. Continuations def strange callcc {|continuation| return continuation} print &quot;Back in method. &quot; end print &quot;Before method. &quot; continuation = strange() print &quot;After method. &quot; continuation .call if continuation Before method. After method. Back in method. After method. RETURN THIS
  • 36. Symbols :this_is_a_symbol :’This is also a symbol’ Has both integer and string representations Is immutable Quicker to lookup than strings Quicker to compare No need to construct a string literal when doing lookups

Editor's Notes

  • #3: Anonymous chunk of code - Equivalent styles – {} and do...end
  • #4: - Can be associated with methods - Method invokes the block using ‘yield’
  • #5: Can have parameters Used in: iterators for wrapping actions (e.g. File.open)
  • #7: - A block converted to an object - Lambda – same as Proc.new, except: - Proc objects checks the number of parameters passed - scope of return in lambda is the block scope, not enclosing scope.
  • #9: Can convert a code block into a Proc object by using ‘&amp;’
  • #10: - functions can be assigned to variables - can be passed as parameters - can be returned from methods
  • #11: A stored block (stored in a variable) with a closed context Context is fixed to the context where the Proc object was created Associated with a block (and hence a Proc object) is all the context in which the block was defined: the value of self and the methods, variables, and constants in scope. Part of the magic of Ruby is that the block can still use all this original scope information even if the environment in which it was defined would otherwise have disappeared. In other languages, this facility is called a closure.
  • #13: Ruby has Open classes – that allow you to: Add a method to an existing class Add a method to an object of a class
  • #14: Simplified version of what rails does in ActiveSupport::CoreExtensions::Numeric::Time
  • #15: The method added is called a singleton method
  • #16: Every object in Ruby has its own singleton class aka eigenclass Singleton methods live in this singleton class Singleton class is: an object (instance of Class) anonymous – has no name REMEMBER – classes are objects too – (instances of class Class). the singleton class of a class is called a metaclass .
  • #17: The two approaches here are equivalent (ignoring a minor point regarding the scope of constants)
  • #18: Can use extend instead opening class to make methods in module available
  • #19: A common use of the class &lt;&lt; notation is for class method definitions. The above three ways of defining a class method are equivalent
  • #20: Normally singleton methods are only available to the object they belong to. An exception is class methods – they are available to subclasses
  • #23: alias_method :new_id, :existing_id
  • #28: Using class_eval . class_eval should be called on a class self.class is the same as Echo
  • #29: self.class is the same as Echo
  • #36: - allows entire execution context to be saved - could be used instead of threads - shared concurrency - have complete control instead of letting Thread scheduler decide.
  • #37: The following statements are handy in using (or not using) symbols: A Ruby symbol looks like a colon followed by characters. (:mysymbol) A Ruby symbol is a thing that has both a number (integer) and a string. The value of a Ruby symbol&apos;s string part is the name of the symbol, minus the leading colon. A Ruby symbol cannot be changed at runtime. Neither its string representation nor its integer representation can be changed at runtime. Ruby symbols are useful in preventing modification. Like most other things in Ruby, a symbol is an object. When designing a program, you can usually use a string instead of a symbol. Except when you must guarantee that the string isn&apos;t modified. Symbol objects do not have the rich set of instance methods that String objects do. After the first usage of :mysymbol all further useages of :mysymbol take no further memory -- they&apos;re all the same object. Ruby symbols save memory over large numbers of identical literal strings. Ruby symbols enhance runtime speed to at least some degree.