Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ruby and the tools 740Tools07RubyMetaprogramming Topics Blocks Yield Iterators Mix-ins Spring 2014 CSCE 740 Software Engineering.

Similar presentations


Presentation on theme: "Ruby and the tools 740Tools07RubyMetaprogramming Topics Blocks Yield Iterators Mix-ins Spring 2014 CSCE 740 Software Engineering."— Presentation transcript:

1 Ruby and the tools 740Tools07RubyMetaprogramming Topics Blocks Yield Iterators Mix-ins Spring 2014 CSCE 740 Software Engineering

2 – 2 – CSCE 740 Spring 2014 Tools - Last Time Blocks Iterators Closures New Ruby Yield Iterators Duck-Typing Mix-ins Next Time: System Modelling

3 – 3 – CSCE 740 Spring 2014 REMEMBER! a.b means: call method b on object a a is the receiver to which you send the method call, assuming a will respond to that 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 – 4 – CSCE 740 Spring 2014 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 – 5 – CSCE 740 Spring 2014 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 – 6 – CSCE 740 Spring 2014 long lines  multiple lines http://pastebin.com/dFJjugTf # downcase and split are defined in String class words = IO.read("file"). split(/\W+/). split(/\W+/). select { |s| s =~ /^[aeiou]/i }. select { |s| s =~ /^[aeiou]/i }. map { |s| s.downcase }. map { |s| s.downcase }. uniq. uniq. sort sort

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

8 – 8 – CSCE 740 Spring 2014 3.5 All Programming is Metaprogramming attr_accessor :year creating code at run-time SaaS book 2012 Fox Patterson

9 – 9 – CSCE 740 Spring 2014 # Note: Time.now returns current time as seconds since epoch class Fixnum def seconds ; self ; end def seconds ; self ; end def minutes ; self * 60 ; end def minutes ; self * 60 ; end def hours ; self * 60 * 60 ; end def hours ; self * 60 * 60 ; end def ago ; Time.now - self ; end def ago ; Time.now - self ; end def from_now ; Time.now + self ; end def from_now ; Time.now + self ; endend 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 – 10 – CSCE 740 Spring 2014 method_missing http://pastebin.com/G0ztHTTP class Fixnum def method_missing(method_id, *args) def method_missing(method_id, *args) name = method_id.to_s name = method_id.to_s if name =~ /^(second|minute|hour)$/ if name =~ /^(second|minute|hour)$/ self.send(name + 's') self.send(name + 's') else else super # pass the buck to superclass super # pass the buck to superclass end end end

11 – 11 – CSCE 740 Spring 2014 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 – 12 – CSCE 740 Spring 2014 Loops—but don’t think of them that way ["apple", "banana", "cherry"].each do |string| puts string puts stringend for i in (1..10) do puts i puts iend 1.upto 10 do |num| puts num puts numend 3.times { print "Rah, " } UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

13 – 13 – CSCE 740 Spring 2014 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|... end hsh.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 – 14 – CSCE 740 Spring 2014 “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 fruit.reverse end.sort # => ['ananab','elppa','elppa','yrrehc'] # => ['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 ananab anana The above code won’t run due to syntax error(s) naan ☐ ☐ ☐ ☐ 15 Which string will not appear in the result of: ['banana','anana','naan'].map do |food| food.reverse end.select { |f| f.match /^a/ } UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

16 – 16 – CSCE 740 Spring 2014 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 – 17 – CSCE 740 Spring 2014 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 – 18 – CSCE 740 Spring 2014 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 – 19 – CSCE 740 Spring 2014 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 – 20 – CSCE 740 Spring 2014 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 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 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 – 21 – CSCE 740 Spring 2014 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 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 Works, because account balances (numbers) get compared ☐ ☐ ☐ ☐ 22 a = SavingsAccount.new(100) b = SavingsAccount.new(50) c = SavingsAccount.new(75) What’s result of [a,b,c].sort UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

23 – 23 – CSCE 740 Spring 2014 Making accounts comparable Just define and then use the Comparable module to get the other methods Now, an Account quacks like a numeric Now, an Account quacks like a numeric http://pastebin.com/itkpaqMh UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

24 – 24 – CSCE 740 Spring 2014 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 – 25 – CSCE 740 Spring 2014 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)) '(lambda (x) (+ x 2)) (filter '(lambda (x) (even? x)) mylist)) (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 – 26 – CSCE 740 Spring 2014 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 – 27 – CSCE 740 Spring 2014 http://pastebin.com/0sTEMcdN <html> Report Report...user-generated content here......user-generated content here... </html> SaaS book 2012 Fox Patterson

28 – 28 – CSCE 740 Spring 2014 1 def one_page 1 def one_page 2 page = ’’ 2 page = ’’ 3 page << make_header() 3 page << make_header() 4 page << "Hello" 4 page << "Hello" 5 page << make_footer() 5 page << make_footer() 6 end 7 def another_page 6 end 7 def another_page 8 page = ’’ 8 page = ’’ 9 page << make_header() 10 page << "World" 11 page << make_footer() 12 end SaaS book 2012 Fox Patterson

29 – 29 – CSCE 740 Spring 2014 http://pastebin.com/TsvTN5ZT def make_page(contents) page = '' page = '' page << make_header() page << make_header() page << contents page << contents page << make_footer() page << make_footer()end# def one_page make_page("Hello") make_page("Hello")end def another_page make_page("World") make_page("World")end

30 – 30 – CSCE 740 Spring 2014 http://pastebin.com/zQPh70NJ def make_page page = '' page = '' page << make_header() page << make_header() page << yield page << yield page << make_footer() page << make_footer()end def one_page make_page do make_page do "Hello" "Hello" end endend def another_page … SaaS book 2012 Fox Patterson

31 – 31 – CSCE 740 Spring 2014 We can exploit Ruby’s idiom for single-line blocks to boil this down to: http://pastebin.com/Nqe8MwA5 def make_page make_header << yield << make_footer make_header << yield << make_footerend def one_page make_page { "Hello" } make_page { "Hello" }end def another_page make_page { "World" } make_page { "World" }end SaaSbook http://pastebin.com/Nqe8MwA5

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

33 – 33 – CSCE 740 Spring 2014 Iterators are just one nifty use of yield # in some other library def before_stuff...before code......before code...end def after_stuff...after code......after code...end # in your code def do_everything before_stuff() before_stuff() my_custom_stuff() my_custom_stuff() after_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 With yield(): expose 1 call in other library UCB CS169 Sp 2012 Slides Fox, Patterson and Sen

34 – 34 – CSCE 740 Spring 2014 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 – 35 – CSCE 740 Spring 2014 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 – 36 – CSCE 740 Spring 2014 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


Download ppt "Ruby and the tools 740Tools07RubyMetaprogramming Topics Blocks Yield Iterators Mix-ins Spring 2014 CSCE 740 Software Engineering."

Similar presentations


Ads by Google