1 / 36

Ruby and the tools 740Tools07RubyMetaprogramming

Ruby and the tools 740Tools07RubyMetaprogramming. CSCE 740 Software Engineering. Topics Blocks Yield Iterators Mix-ins. Spring 2014. Tools -. Last Time Blocks Iterators Closures. New Ruby Yield Iterators Duck-Typing Mix-ins Next Time: System Modelling. REMEMBER!.

tadita
Télécharger la présentation

Ruby and the tools 740Tools07RubyMetaprogramming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Ruby and the tools740Tools07RubyMetaprogramming CSCE 740 Software Engineering • Topics • Blocks • Yield • Iterators • Mix-ins Spring 2014

  2. Tools - • Last Time • Blocks • Iterators • Closures • New Ruby • Yield • Iterators • Duck-Typing • Mix-ins • Next Time: System Modelling

  3. REMEMBER! • a.bmeans: call method b on object a • a is the receiver to which you sendthe method call, assuming a will respond tothat method • does not mean:b is an instance variable of a • does not mean: a is some kind of data structure that has b as a member • 5.class.superclass Understanding this distinction will save you from much grief and confusion UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  4. 3.2 Everything is an Object - revisited • “Ruby’s object model descends from Smalltalk, whose design was inspired by ideas in Simula.” • Ruby: • is dynamically typed • is lexically scoped • does not support multiple inheritance • supports reflection (asking about objects) • “Even a class in Ruby is itself an object—it’s an instance of Class, which is a class whose instances are classes (a metaclass).” • def class xxx … SaaS book 2012 Fox Patterson

  5. Poetry Mode revisited • To improve readability by removing clutter: • omit parentheses, braces as long as parsing remains unambiguous • spreading long lines over multiple lines • using “ ; ” instead of newline as separator • surround “;” with spaces – making meaner clearer • attr_accessor :year SaaS book 2012 Fox Patterson

  6. long lines multiple lines http://pastebin.com/dFJjugTf • # downcase and split are defined in String class • words = IO.read("file"). •   split(/\W+/). •   select { |s| s =~ /^[aeiou]/i }. •   map { |s| s.downcase }. • uniq. •   sort

  7. http://pastebin.com/K6ev3S7g Splat Args • # using 'keyword style' arguments • defmymethod(required_arg, args={}) • do_fancy_stuff if args[:fancy] • end • mymethod "foo",:fancy => true # => args={:fancy => true} • mymethod "foo"                # => args={} • # using * (splat) arguments • defmymethod(required_arg, *args) •   # args is an array of extra args, maybe empty • end  • mymethod "foo","bar",:fancy => true # => args=["bar",{:fancy=>true}] • mymethod "foo"                      # => args=[]

  8. 3.5 All Programming is Metaprogramming • attr_accessor :year • creating code at run-time SaaS book 2012 Fox Patterson

  9. #  Note: Time.now returns current time as seconds since epoch • class Fixnum • def seconds  ; self ; end • def minutes  ; self * 60 ; end • def hours    ; self * 60 * 60 ; end • def ago      ; Time.now - self ; end • deffrom_now ; Time.now + self ; end • end • Time.now     # => Mon Nov 07 10:18:10 -0800 2011 • 5.minutes.ago # => Mon Nov 07 10:13:15 -0800 2011 • 5.minutes - 4.minutes # => 60 • 3.hours.from_now # => Mon Nov 07 13:18:15 -0800 2011

  10. method_missinghttp://pastebin.com/G0ztHTTP • class Fixnum • defmethod_missing(method_id, *args) •     name = method_id.to_s •     if name =~ /^(second|minute|hour)$/ • self.send(name + 's') •     else •       super # pass the buck to superclass •     end •   end • end

  11. 3.6 Blocks: Iterators, Functional Idioms, and Closures • Fox, Armando; Patterson, David (2014-01-31). Engineering Software as a Service: An Agile Approach Using Cloud Computing (Kindle Location 2514). Strawberry Canyon LLC. Kindle Edition.

  12. Loops—but don’t think of them that way ["apple", "banana", "cherry"].each do |string| puts string end for i in (1..10) do puts i end 1.upto 10 do |num| puts num end 3.times { print "Rah, " } UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  13. If you’re iterating with an index, you’re probably doing it wrong • Iterators let objects manage their own traversal • (1..10).each do |x| ... end(1..10).each { |x| ... }1.upto(10) do |x| ... end=> range traversal • my_array.each do |elt| ... end=> array traversal • hsh.each_key do |key| ... endhsh.each_pair do |key,val| ... end=> hash traversal • 10.times {...} # => iterator of arity zero • 10.times do ... end UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  14. “Expression orientation” x = ['apple','cherry','apple','banana'] x.sort # => ['apple','apple','banana','cherry'] x.uniq.reverse # => ['banana','cherry','apple'] x.reverse! # => modifies x x.map do |fruit| fruit.reverse end.sort # => ['ananab','elppa','elppa','yrrehc'] x.collect { |f| f.include?("e") } x.any? { |f| f.length > 5 } • A real life example.... http://pastebin.com/Aqgs4mhE UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  15. Which string will not appear in the result of: ['banana','anana','naan'].map do |food| food.reverse end.select { |f| f.match /^a/ } naan ☐ ananab ☐ anana ☐ The above code won’t run due to syntax error(s) ☐ UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  16. Collection Operators • Method - #Args - Returns a new collection containing. . . • c.map 1 - elements obtained by applying block to each element of c • c.select 1 Subset of c for which block evaluates to true • c.reject 1 Subset of c obtained by removing elements for which block evaluates to true • c.uniq all elements of c with duplicates removed • c.reverse elements of c in reverse order • c.compact all non-nil elements of c • c.flatten elements of c and any of its sub-arrays, recursively flattened to contain only non-array elements

  17. More Collection Operators • c.sort -If sort is called without a block, the elements are sorted according to how they respond to <=>. • c.partition • c.sort_by • c.max • c.min • Fox, Armando; Patterson, David (2014-01-31). Engineering Software as a Service: An Agile Approach Using Cloud Computing (Kindle Locations 2594-2595). Strawberry Canyon LLC. Kindle Edition.

  18. What is “duck typing”? • If it responds to the same methods as a duck...it might as well be a duck • More than just overloading; similar to Java Interfaces • Example: my_list.sort [5, 4, 3].sort ["dog", "cat", "rat"].sort [:a, :b, :c].sort IO.readlines("my_file") UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  19. Modules • A module is a collection of class & instance methods that are not actually a class • you can’t instantiate it • Some modules are namespaces, similar to Python: Math::sin(Math::PI / 2.0) • The more interesting ones let you mix the methods into a class: class A < B ; include MyModule ; end • A.foo will search A, then MyModule, then B • sort is actually defined in module Enumerable, which is mixed into Array by default UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  20. A Mix-in Is A Contract • Example: Enumerable assumes objects of target class respond to each • ...provides all?, any?, collect, find, include?, inject, map, partition, .... • Example: Comparable assumes that objects of target class respond to <=> • provides < <= => > == between?for free • Enumerable also provides sort, which requires elements of target class (things returned by each) to respond to <=> Class of objects doesn’t matter: only methods to which they respond UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  21. Example: sorting a file • Sorting a file • File.open returns an IO object • IO objects respond to each by returning each line as a String • So we can say File.open('filename.txt').sort • relies on IO#each and String#<=> • Which lines of file begin with vowel? File.open('file').select { |s| s =~ /^[aeiou]/i } UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  22. a = SavingsAccount.new(100) b = SavingsAccount.new(50) c = SavingsAccount.new(75) What’s result of [a,b,c].sort Works, because account balances (numbers) get compared ☐ Doesn’t work, but would work if we passed a comparison method to sort ☐ Doesn’t work, but would work if we defined <=> on SavingsAccount ☐ Doesn’t work: SavingsAccount isn’t a basic Ruby type so can’t compare them ☐ UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  23. Making accounts comparable • Just define<=> and then use the Comparable module to get the other methods • Now, an Account quacks like a numeric  http://pastebin.com/itkpaqMh UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  24. When Module? When Class? • Modules reuse behaviors • high-level behaviors that could conceptually apply to many classes • Example: Enumerable, Comparable • Mechanism: mixin (include Enumerable) • Classes reuse implementation • subclass reuses/overrides superclass methods • Mechanism: inheritance (class A < B) • Remarkably often, we will prefer composition over inheritance UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  25. Blocks (anonymous λ) (map '(lambda (x) (+ x 2)) mylist ) mylist.map { |x| x+2 } (filter '(lambda (x) (even? x)) mylist) mylist.select do |x| ; x.even? ; end (map '(lambda (x) (+ x 2)) (filter '(lambda (x) (even? x)) mylist)) mylist.select {|x| x.even?}.map {|x| x+2 } UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  26. Turning iterators inside-out • Java: • You hand me each element of that collection in turn. • I’ll do some stuff. • Then I’ll ask you if there’s any more left. • Ruby: • Here is some code to apply to every element of the collection. • You manage the iteration or data structure traversal. • Let’s do an example... http://pastebin.com/T3JhV7Bk UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  27. http://pastebin.com/0sTEMcdN • <!DOCTYPE html> • <html> • <head> • <title>Report</title> • </head> • <body> • <div id="main"> • ...user-generated content here... • </div> • </body> • </html> SaaS book 2012 Fox Patterson

  28.  1    defone_page • 2      page = ’’   • 3      page << make_header()   • 4      page << "Hello"   • 5      page << make_footer()   • 6    end  7    defanother_page • 8      page = ’’   • 9      page << make_header() • 10      page << "World" • 11      page << make_footer() • 12    end SaaS book 2012 Fox Patterson

  29. http://pastebin.com/TsvTN5ZT • defmake_page(contents) •   page = '' •   page << make_header() •   page << contents •   page << make_footer() • end • # • defone_page • make_page("Hello") • end • defanother_page • make_page("World") • end

  30. http://pastebin.com/zQPh70NJ • defmake_page •   page = '' •   page << make_header() •   page << yield •   page << make_footer() • end • defone_page • make_page do •     "Hello" •   end • end • defanother_page • … SaaS book 2012 Fox Patterson

  31. We can exploit Ruby’s idiom for single-line blocks to boil this down to: http://pastebin.com/Nqe8MwA5 • defmake_page • make_header << yield << make_footer • end • defone_page • make_page { "Hello" } • end • defanother_page • make_page { "World" } • end SaaSbook http://pastebin.com/Nqe8MwA5

  32. http://pastebin.com/T3JhV7Bk • class RandomSequence • def initialize(limit,num) •     @limit,@num = limit,num •   end • def each •     @num.times { yield (rand * @limit).floor } •   end • end UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  33. Iterators are just one nifty use of yield # in some other library def before_stuff ...before code... end def after_stuff ...after code... end # in your code def do_everything before_stuff() my_custom_stuff() after_stuff() end Without yield(): expose 2 calls in other library # in some other library def around_stuff ...before code... yield ...after code... end # in your code def do_everything around_stuff do my_custom_stuff() end end With yield(): expose 1 call in other library UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  34. Blocks are Closures • A closure is the set of all variable bindings you can “see” at a given point in time • In Scheme, it’s called an environment • Blocks are closures: they carry their environment around with them • Result: blocks can help reuse by separating what to do from where & when to do it • We’ll see various examples in Rails http://pastebin.com/zQPh70NJ UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

  35. Summary of Yield • In the body of a method that takes a block as a parameter, yield transfers control to the block and optionally passes it an argument. • A block is a closure, its scope is the one that was in effect when the block was defined, • Yielding is the general mechanism behind iterators: • an iterator is simply a method that traverses some data structure and uses yield to pass one element at a time to the iterator’s receiver. SaaS book 2012 Fox Patterson

  36. 3.9 Fallacies and Pitfalls • Pitfall: Writing Java in Ruby • Pitfall: Thinking of symbols and strings as interchangeable. • Pitfall: Naming a local variable when you meant a local method. • Pitfall: Confusing require with include. • Fox, Armando; Patterson, David (2014-01-31). Engineering Software as a Service: An Agile Approach Using Cloud Computing (Kindle Locations 2811-2812). Strawberry Canyon LLC. Kindle Edition. SaaS book 2012 Fox Patterson

More Related