These are two Rails helpers that could be very useful when injecting new instance methods in a class.

underscore

Converts from a class name to a underscore attribute.


>> 'MyClassName'.underscore => my_class_name

classify

Inverse method from underscore.


  >> "cool_articles".classify
=> "CoolArticles"

>> "comment".classify
=> "Comment"

Both, combined with singularize and pluralize, allows us to handle parent/child methods in a very handy way. For example:


elements_in_ = self.send(parent).send(self.class.to_s.pluralize.underscore)

or things like


Kernel.const_get(table_model.to_s.classify).find(:all) #Kernel.const_get gets an string and retrieves the class.

Advertisements

Procs ‘n’ blocks

May 1, 2008

A block in Ruby is an expression delimited by braces that has, to try to put it simple, no life by itself. Thus if we write:


irb(main):001:0> {|x| x*x}
SyntaxError: compile error

we’ll get a compile error. But blocks can be very powerful and go by the hand with other important concept in Ruby, namely the Procs. Procs, put again in a simple way, are blocks given life, thus are blocks bounded to some variables they can work with. To create a new proc, we can simply call the constructor of the class Proc or the kernel reserved word lambda, what will get us to the same thing, except that the latter will provide us argument checking. Thus:


irb(main):002:0> my_proc = Proc.new{|x| x*x}
=> #<Proc:0x00006a7c@(irb):2>
irb(main):003:0> my_other_proc = lambda{|x| x*x}
=> #<Proc:0x00086640@(irb):3>
irb(main):005:0> my_proc.call(5)
=> 25
irb(main):006:0> my_other_proc.call(5, 4)
(irb):3: warning: multiple values for a block parameter (2 for 1)
        from (irb):7
TypeError: can't convert Array into Integer
        from (irb):3:in `*'
        from (irb):3
        from (irb):7
        from :0
irb(main):007:0> my_other_proc.call(5)
=> 25

Notice that a proc is executed by using the reserved word call. That means that we have to use it instead of yield when we are passing a proc rather than a block to a method:


irb(main):032:0> def gimme_those_five
irb(main):033:1> 5.times {yield}
irb(main):034:1> end
=> nil
irb(main):035:0> gimme_those_five{puts "hi"}
hi
hi
hi
hi
hi
=> 5

but


irb(main):038:0> def gimme_just_one(kind)
irb(main):039:1> kind.call
irb(main):040:1> end
=> nil
irb(main):041:0> gimme_just_one lambda{puts "hi"}
hi
=> nil