ruby and the tools 740tools07rubymetaprogramming
Download
Skip this Video
Download Presentation
Ruby and the tools 740Tools07RubyMetaprogramming

Loading in 2 Seconds...

play fullscreen
1 / 36

Ruby and the tools 740Tools07RubyMetaprogramming - PowerPoint PPT Presentation


  • 95 Views
  • Uploaded on

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!.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Ruby and the tools 740Tools07RubyMetaprogramming' - tadita


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
ruby and the tools 740tools07rubymetaprogramming
Ruby and the tools740Tools07RubyMetaprogramming

CSCE 740 Software Engineering

  • Topics
    • Blocks
    • Yield
    • Iterators
    • Mix-ins

Spring 2014

tools
Tools -
  • Last Time
    • Blocks
    • Iterators
    • Closures
  • New Ruby
    • Yield
    • Iterators
    • Duck-Typing
    • Mix-ins
  • Next Time: System Modelling
remember
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

3 2 everything is an object revisited
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

poetry mode revisited
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

long lines multiple lines http pastebin com dfjjugtf
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
http pastebin com k6ev3s7g splat args
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=[]
3 5 all programming is metaprogramming
3.5 All Programming is Metaprogramming
  • attr_accessor :year
  • creating code at run-time

SaaS book 2012 Fox Patterson

slide9

#  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
method missing http pastebin com g0zthttp
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
3 6 blocks iterators functional idioms and closures
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.
loops but don t think of them that way
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

if you re iterating with an index you re probably doing it wrong
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

expression orientation
“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

slide15

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

collection operators
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
more collection operators
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.
what is duck typing
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

modules
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

a mix in is a contract
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

example sorting a file
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

slide22

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

making accounts comparable
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

when module when class
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

blocks anonymous
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

turning iterators inside out
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

http pastebin com 0stemcdn
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

slide28

 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

http pastebin com tsvtn5zt
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
http pastebin com zqph70nj
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

slide31

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

http pastebin com t3jhv7bk
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

iterators are just one nifty use of yield
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

blocks are closures
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

summary of yield
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

3 9 fallacies and pitfalls
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

ad