Can We Pass Block from Function to Function?
Author Message
Can We Pass Block from Function to Function?

Hi,

I have two functions that each takes a block:

def func1 (arg1, &arg2)
....
end

def func2 (arg1, &arg2)
....
func1 (x, ???) ???
....
end

Can we pass the block from func2 to func1?  If yes, how?  (It seems there
is no way to convert back from a Proc object to a block.)

Regards,

Bill

Tue, 15 Feb 2005 22:26:34 GMT
Can We Pass Block from Function to Function?

[...]
Quote:
>      def func1 (arg1, &arg2)
>          ....
>      end

>      def func2 (arg1, &arg2)

func1(arg1, &arg2)

Quote:
>      end

>  Can we pass the block from func2 to func1?  If yes, how?  (It seems there
>  is no way to convert back from a Proc object to a block.)

Make it the last argument, and prefix it with "&" as above. Another
example (it has needless overhead in creating a Proc object only to
discard it, but illustrates the point):

10.times &proc{|x| p x}

Hope this helps.

Reimer Behrends

Tue, 15 Feb 2005 22:51:42 GMT
Can We Pass Block from Function to Function?
Prefix the Proc with "&" to convert it back to a block:

def func2 (arg1,  &proc)
func1 (x, &proc)
end

Cheers,
Nat.

Quote:

> I have two functions that each takes a block:

>     def func1 (arg1, &arg2)
>         ....
>     end

>     def func2 (arg1, &arg2)
>         ....
>         func1 (x, ???) ???
>         ....
>     end

> Can we pass the block from func2 to func1?  If yes, how?  (It seems there
> is no way to convert back from a Proc object to a block.)

--
Dr. Nathaniel Pryce, Technical Director, B13media Ltd.
Studio 3a, 22-24 Highbury Grove, London N5 2EA, UK
http://www.b13media.com

Tue, 15 Feb 2005 23:01:20 GMT
Can We Pass Block from Function to Function?
Thanks a lot.  It works!  When I checked the methods of class Proc in the
"Programming Ruby" book, they cover only "new", "[]", "arity", and
"call".  Probably this use of "&" to convert back is described in the "The
Ruby Language" section.

Logically, does this "&" operator belong to the Proc class, the Object
class, or the Kernel module?

Regards,

Bill
============================================================================

Quote:

>>  Can we pass the block from func2 to func1?  If yes, how?  (It seems there
>>  is no way to convert back from a Proc object to a block.)
> Make it the last argument, and prefix it with "&" as above. Another
> example (it has needless overhead in creating a Proc object only to
> discard it, but illustrates the point):
>    10.times &proc{|x| p x}
> Hope this helps.
>                    Reimer Behrends

Tue, 15 Feb 2005 23:06:44 GMT
Can We Pass Block from Function to Function?

[...]

Quote:
>  Logically, does this "&" operator belong to the Proc class, the Object
>  class, or the Kernel module?

It is not a standard operator like "+" that is converted into a method
call (and thus can't be redefined, either), so it isn't listed as part
of the Proc class. "&" is essentially syntactic sugar to tell the
compiler to use the Proc object as a block, much like the "*" prefix is
used with arrays to handle a variable number of arguments.

Reimer Behrends

Tue, 15 Feb 2005 23:14:51 GMT
Can We Pass Block from Function to Function?
Hi,

Thanks for your response.  The reason I asked is because usually when I
know the class, I can write it in C as

rb_funcall (rb_cKlass, rb_intern ("the operator"), n, ...);

Can you help to write the statement

func1 (arg1, &arg2)

in C?  I am still struggling on how to covert this Proc "&" operator to
C.  (Well, everything else fails, there is always that
"rb_eval_string()" ultimate weapon :) )

Regards,

Bill
==========================================================================

Quote:

> [...]
>>  Logically, does this "&" operator belong to the Proc class, the Object
>>  class, or the Kernel module?
> It is not a standard operator like "+" that is converted into a method
> call (and thus can't be redefined, either), so it isn't listed as part
> of the Proc class. "&" is essentially syntactic sugar to tell the
> compiler to use the Proc object as a block, much like the "*" prefix is
> used with arrays to handle a variable number of arguments.
>                    Reimer Behrends

Tue, 15 Feb 2005 23:28:54 GMT
Can We Pass Block from Function to Function?

Quote:

> Can we pass the block from func2 to func1?  If yes, how?  (It seems there
> is no way to convert back from a Proc object to a block.)

this brings up some interesting notions, when i first read pickaxe, this
was the one thing i did not like about ruby. why are there three diffent
things for essentially the same construction: block, procs, and methods?
methods, i can see have a distinction in that they are tied on an
object, like an instance variable is, but still.

so then one is also left thinking, why not multiple blocks?

personally i wish { } brackets always represented a proc and that we
could pass them easily (and also not require a #call to execute them):

def ameth(proc1, proc2)
proc1()
proc2()
end

ameth({puts 'hello'},{puts 'world'})

> hello
> world

then a proc...excuse me, a block, is just a Yeild-able proc. yes, that's
it.

~transami

Wed, 16 Feb 2005 00:04:19 GMT
Can We Pass Block from Function to Function?

Quote:

> personally i wish { } brackets always represented a proc and that we
> could pass them easily (and also not require a #call to execute them):

>    def ameth(proc1, proc2)
>      proc1()
>      proc2()
>    end

>    ameth({puts 'hello'},{puts 'world'})

>    > hello
>         > world

> then a proc...excuse me, a block, is just a Yeild-able proc. yes, that's
> it.

The advantage of using a call method, rather than some special syntax,
is that it's always possible to implement your own class that
understands call(...), and objects of that class are then
interchangeable with Procs, Methods and any other callable object.

On a related note, I wish that the Ruby interpreter performed automagic
optimisation on Procs/blocks, in the same way that it optimises integers
behind the scenes.

I'd like it if there was no visible difference between a proc and a
block.  At the language level, you would only use proc objects, and
invoke them with the call method.  Internally, the Ruby interpreter
would decide whether to use a block as an optimisation, or instantiate a
Proc object.

Cheers,
Nat.

--
Dr. Nathaniel Pryce, Technical Director, B13media Ltd.
Studio 3a, 22-24 Highbury Grove, London N5 2EA, UK
http://www.b13media.com

Wed, 16 Feb 2005 00:24:24 GMT
Can We Pass Block from Function to Function?
..

Quote:
> Can you help to write the statement

>     func1 (arg1, &arg2)

> in C?  I am still struggling on how to covert this Proc "&" operator to
> C.  (Well, everything else fails, there is always that
> "rb_eval_string()" ultimate weapon :) )

Maybe rb_iterate is what you're looking for. From the Pickaxe:

VALUE rb_iterate(VALUE (*method)(), VALUE args, VALUE (*block)(),
VALUE arg2)

Invokes method with argument args and block block. A yield from
that method will invoke block with the argument given to yield, and
a second argument arg2.

So you would have to wrap your method, func1, and your proc, arg2,
inside two C functions, and pass pointers to them as method and block in
the prototype.

I wish there were an rb_iterate2 or something which accepted a symbol
and a proc as VALUEs, to save you from having to wrap them in functions.

Wed, 16 Feb 2005 08:42:48 GMT

 Page 1 of 1 [ 9 post ]

Relevant Pages