On Friday, May 20, 2011 2:18:50 PM UTC-6, Ruby-Forum.com User wrote: > > Hey all, > > I have a question about this line of code: > > within "#main-menu" do > find("h6", :text => menu).click if menu > click_link link > end > > def within(selector, &blk) > new_blk = proc do > begin > scope_selectors.push(selector) > blk.call > ensure > scope_selectors.pop > end > end > super(selector.strip, &new_blk) > end > > First, when within is called, it obviously passes the string > "#main-menu", but does it also pass the block (the content between do > and end) as the second argument? The reason why I ask is because notice > within requires a second argument: &blk. > Yes it does. This is a standard feature/part of ruby. When defining a method, you may always put, as the last entry in the list of parameters, a parameter with the ampersand '&' prefixed to its name. This "captures" (gives you direct access) any block passed to the method by making it available as a Proc instance. Otherwise, any block would still be passed in (if you called #block_given? it would return true) but the only way to "access" it is to call #yield.
So the #within method "captures" any block passed to it and it gets stored as a Proc instance, referenced by blk. Second, we create a proc to convert a code block into an object and > store that object into new_blk local variable. Then we call the object > in the super argument list, which adds the selector (e.g. "#main-menu") > into the scope_selectors array. > There is no "call" on the new_blk variable. The entire method definition is pretty much composed of the new Proc's definition (all except the last line that calls #super). The "&new_blk" entry in #super's argument list does the inverse of what the ampersand in #within's method definition does. In essence, an entry like: "&arg" in a method definition "captures" a block (as a proc) while a similar entry in a method call "sets it free" by making the proc appear just as if you'd passed a normal code block to the method. Example: def asdf(&arg) arg.call end Is "effectively" equivalent to def asdf yield end And then: asdf { puts "hi" } is effectively equivalent to: x = proc { puts "hi" } asdf(&x) Then it seems like we call the initial > code block (blk.call) > Yes, _inside_ of the new proc stored in new_blk... > adjacent to within(). But the blk code block has > not been > converted to a proc, > This was done implicitly by the #within's method definition parameter list's "&blk" entry as described above. > so how is it possible to have a callable block > then? > > Finally, super is only called on a parent class with a method of the > same name correct? Because in this case, within() is the only method in > entire application. super has another purpose? > I don't know of any other purpose. Does the "super" line result in a NoMethodError being raised? If not, it's finding _some_ method up the chain to call. Is there some other gem or library that adds a #within method to Object or some other ruby magic like #method_missing somewhere up the chain? > Thanks for response. > > -- > Posted via http://www.ruby-forum.com/. > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-talk+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.