Ruby and the tools 740tools07rubymetaprogramming
This presentation is the property of its rightful owner.
Sponsored Links
1 / 36

Ruby and the tools 740Tools07RubyMetaprogramming PowerPoint PPT Presentation


  • 79 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

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


Ruby and the tools 740tools07rubymetaprogramming

  • #  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


Ruby and the tools 740tools07rubymetaprogramming

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


Ruby and the tools 740tools07rubymetaprogramming

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


Ruby and the tools 740tools07rubymetaprogramming

  •  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


Ruby and the tools 740tools07rubymetaprogramming

  • 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


  • Login