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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.