[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to "pass" the current binding's block to some other method?

Lyle Johnson

2/8/2007 10:52:00 PM

Suppose I have a method that will yield to a block if one is given:

def try(x, y, z)
# ... do some other stuff first ...
yield self if block_given?
end

Now suppose that I create an alias to this method, for the purpose of
overriding how it's called, e.g.

alias old_try try
def try(hash)
old_try(hash[:x], hash[:y], hash[:z])
end

If someone calls this new and improved version of try() and provides a
block, is there any way for me to somehow pass that block down into
old_try() without actually modifying the method signature?

11 Answers

Gavin Kistner

2/8/2007 10:57:00 PM

0

On Feb 8, 3:52 pm, "Lyle Johnson" <lyle.john...@gmail.com> wrote:
> Suppose I have a method that will yield to a block if one is given:
>
> def try(x, y, z)
> # ... do some other stuff first ...
> yield self if block_given?
> end
>
> Now suppose that I create an alias to this method, for the purpose of
> overriding how it's called, e.g.
>
> alias old_try try
> def try(hash)
> old_try(hash[:x], hash[:y], hash[:z])
> end
>
> If someone calls this new and improved version of try() and provides a
> block, is there any way for me to somehow pass that block down into
> old_try() without actually modifying the method signature?

Do you feel that this:
def try( hash, &block )
old_try( hash[:x],hash[:y],hash[:z],&block )
end
is somehow changing its signature? (You can still choose to pass a
block or not.)

Lyle Johnson

2/8/2007 11:11:00 PM

0

On 2/8/07, Phrogz <gavin@refinery.com> wrote:

> Do you feel that this:
> def try( hash, &block )
> old_try( hash[:x],hash[:y],hash[:z],&block )
> end
> is somehow changing its signature?

For the purposes of this discussion, yes. Perhaps a better way to
phrase the question is whether there's any way to do it without
modifying the original source code for try().

> (You can still choose to pass a block or not.)

Yes, I get what you're saying. I'm just hoping to not have to modify
the original source (if possible).

Gavin Kistner

2/8/2007 11:46:00 PM

0

On Feb 8, 4:11 pm, "Lyle Johnson" <lyle.john...@gmail.com> wrote:
> On 2/8/07, Phrogz <g...@refinery.com> wrote:
>
> > Do you feel that this:
> > def try( hash, &block )
> > old_try( hash[:x],hash[:y],hash[:z],&block )
> > end
> > is somehow changing its signature?
>
> For the purposes of this discussion, yes. Perhaps a better way to
> phrase the question is whether there's any way to do it without
> modifying the original source code for try().

To be clear: you *only* need to modify your new (overriding) try
method with the &block notation. The original try method's source code
remains unchanged.

(I hope this is what you want. If you can't modify the source code for
your overriding method, I'm not sure how you would intend to use any
code that would pass the block along. :)

Mauricio Fernández

2/8/2007 11:55:00 PM

0

On Fri, Feb 09, 2007 at 08:00:11AM +0900, Phrogz wrote:
> On Feb 8, 3:52 pm, "Lyle Johnson" <lyle.john...@gmail.com> wrote:
[...]
> > alias old_try try
> > def try(hash)
> > old_try(hash[:x], hash[:y], hash[:z])
> > end
> >
> > If someone calls this new and improved version of try() and provides a
> > block, is there any way for me to somehow pass that block down into
> > old_try() without actually modifying the method signature?
>
> Do you feel that this:
> def try( hash, &block )
> old_try( hash[:x],hash[:y],hash[:z],&block )
> end
> is somehow changing its signature? (You can still choose to pass a
> block or not.)

def old_try
yield * 2
end

def try(hash)
old_try(&Proc.new) # probably breaking in 1.9 someday (works right now)
end

try(:a => 1) { "foo" } # => "foofoo"
RUBY_VERSION # => "1.8.5"

--
Mauricio Fernandez - http://eige... - singular Ruby
** Latest postings **
What's new in Ruby 1.9, Feb. 07 update
http://eige.../hiki.rb?Changes-in-Ruby-1.9-update-6
Firebrigade: automated, sandboxed testing of RubyGems packages by other devels
http://eige.../hiki.rb?firebrigade-launched

Joel VanderWerf

2/9/2007 12:21:00 AM

0

Lyle Johnson wrote:
> On 2/8/07, Phrogz <gavin@refinery.com> wrote:
>
>> Do you feel that this:
>> def try( hash, &block )
>> old_try( hash[:x],hash[:y],hash[:z],&block )
>> end
>> is somehow changing its signature?
>
> For the purposes of this discussion, yes. Perhaps a better way to
> phrase the question is whether there's any way to do it without
> modifying the original source code for try().
>
>> (You can still choose to pass a block or not.)
>
> Yes, I get what you're saying. I'm just hoping to not have to modify
> the original source (if possible).

Does this help?

class Foo
def try(x, y, z)
# ... do some other stuff first ...
yield self if block_given?
end

alias old_try try
def try(hash)
old_try(hash[:x], hash[:y], hash[:z]) do
yield self if block_given?
end
end
end

Foo.new.try({}) do puts "trying" end

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Lyle Johnson

2/9/2007 12:32:00 AM

0

On 2/8/07, Phrogz <gavin@refinery.com> wrote:

> To be clear: you *only* need to modify your new (overriding) try
> method with the &block notation. The original try method's source code
> remains unchanged.

Huh. I tried that with my "real" code and got an error (i.e. with Ruby
claiming that the number of arguments passed into old_try was
incorrect). But I just wrote up a short example to test it and it
worked as you described.

OK. I need to figure out what's different about my code. Thanks for
the lead on this!

Lyle Johnson

2/9/2007 12:33:00 AM

0

On 2/8/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

> Does this help?
>
> class Foo
> def try(x, y, z)
> # ... do some other stuff first ...
> yield self if block_given?
> end
>
> alias old_try try
> def try(hash)
> old_try(hash[:x], hash[:y], hash[:z]) do
> yield self if block_given?
> end
> end
> end
>
> Foo.new.try({}) do puts "trying" end

Ah, yes, that ought to do the trick too. Thanks!

Joel VanderWerf

2/9/2007 12:52:00 AM

0

Lyle Johnson wrote:
> On 2/8/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
>
>> Does this help?
>>
>> class Foo
>> def try(x, y, z)
>> # ... do some other stuff first ...
>> yield self if block_given?
>> end
>>
>> alias old_try try
>> def try(hash)
>> old_try(hash[:x], hash[:y], hash[:z]) do
>> yield self if block_given?
>> end
>> end
>> end
>>
>> Foo.new.try({}) do puts "trying" end
>
> Ah, yes, that ought to do the trick too. Thanks!

It *might* be faster, too, if that matters. It doesn't create a Proc
instance.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Ezra Zygmuntowicz

2/9/2007 6:31:00 AM

0


On Feb 8, 2007, at 4:33 PM, Lyle Johnson wrote:

> On 2/8/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
>
>> Does this help?
>>
>> class Foo
>> def try(x, y, z)
>> # ... do some other stuff first ...
>> yield self if block_given?
>> end
>>
>> alias old_try try
>> def try(hash)
>> old_try(hash[:x], hash[:y], hash[:z]) do
>> yield self if block_given?
>> end
>> end
>> end
>>
>> Foo.new.try({}) do puts "trying" end
>
> Ah, yes, that ought to do the trick too. Thanks!
>


def try(x, y, z)
# ... do some other stuff first ...
yield self if block_given?
end

alias old_try try

def try(hash)
old_try(hash[:x], hash[:y], hash[:z], &yield)
end


try( :a => 'foo') { puts 'hi' }


Cheers-

-- Ezra Zygmuntowicz
-- Lead Rails Evangelist
-- ez@engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)



Joel VanderWerf

2/9/2007 7:41:00 AM

0

Ezra Zygmuntowicz wrote:
>
> On Feb 8, 2007, at 4:33 PM, Lyle Johnson wrote:
>
>> On 2/8/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
>>
>>> Does this help?
>>>
>>> class Foo
>>> def try(x, y, z)
>>> # ... do some other stuff first ...
>>> yield self if block_given?
>>> end
>>>
>>> alias old_try try
>>> def try(hash)
>>> old_try(hash[:x], hash[:y], hash[:z]) do
>>> yield self if block_given?
>>> end
>>> end
>>> end
>>>
>>> Foo.new.try({}) do puts "trying" end
>>
>> Ah, yes, that ought to do the trick too. Thanks!
>>
>
>
> def try(x, y, z)
> # ... do some other stuff first ...
> yield self if block_given?
> end
>
> alias old_try try
>
> def try(hash)
> old_try(hash[:x], hash[:y], hash[:z], &yield)
> end
>
>
> try( :a => 'foo') { puts 'hi' }

Cool, &yield is new to me!

But the OP wanted the following to work too, I think:

try( :a => 'foo')

and this will raise a LocalJumpError in this case...

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407