How to use a proc like a method


#1

is there a way to use a proc like a method?

like:

class A
def initialize
@av=10;
end
def do(mproc)
mproc.call();
end
def rt()
@av;
end
end

a=proc{@av=111} #something different
b=A.new
b.do(a)
b.rt #return -> 111

is it possible by makeing subclass of proc to do this?


#2

------------ 8< ------------

class A
def initialize
@av=10;
end
def do(mproc)
#### changed this line ####
instance_eval &mproc
end
def rt()
@av;
end
end

a=proc{@av=111} #something different
b=A.new
b.do(a)
b.rt #return -> 111

------------ 8< ------------

Jacob F.


#3

Now that I answered the simple questions, I’d suggest some style
changes/fixes:

------------ 8< ------------

class A
def initialize
@av = 10 ### [1], [2]
end
def do(&mproc) ### [3]
instance_eval &mproc
end
def rt ### [4]
@av
end
end

a = proc{ @av = 111 } # something different
b = A.new
b.do(&a) ### [5]
b.do { @av = 111 } ### [6]
b.rt # return -> 111

------------ 8< ------------

[1] Ruby doesn’t need a semicolon. The newline is the statement
separator. A semicolon can be used to separate multiple statements on
the same line, however.

[2] Be liberal with your whitespace. This is simply style, but I think
you’ll find most rubyists share this preference.

[3] You can make a method accept a block parameter (such as Array#each
does) by prepending the last parameter in the parameter list with an
ampersand (&).

[4] If you are defining a method with no parameters, it’s acceptable
to leave off the empty parentheses. This is also just style and may be
debated.

[5] You can change a Proc object into a block with the & prefix. (In
fact, you can turn any object into a block with & and a properly
defined to_proc method. Whether doing so is good practice is
debatable.)

[6] The obvious alternative to creating an explicit proc then
converting that proc to a block.

Jacob F.


#4

On Dec 19, 2005, at 4:19 PM, Jacob F. wrote:

[5] You can change a Proc object into a block with the & prefix. (In
fact, you can turn any object into a block with & and a properly
defined to_proc method. Whether doing so is good practice is
debatable.)

This doesn’t seem quite accurate to me. The expression generated
by the use of ‘&’ in a method call is an instance of Proc. If the
expression prefixed by ‘&’ is already an instance of Proc then
no conversion of any type occurs, the object is passed ‘as is’ to
the method.

If might be more accurate to say:

Instead of using a literal block in a method call, you can arrange
for any object to be passed as the ‘block argument’ to the method
with the ‘&’ prefix operator:

method(arg1, arg2, arg3, &block_arg)

If ‘block_arg’ is not an instance of Proc, then block_arg.to_proc
is called and the result, which must be an instance of Proc, is
passed to the method instead.


#5

On 12/19/05, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

no conversion of any type occurs, the object is passed ‘as is’ to
If ‘block_arg’ is not an instance of Proc, then block_arg.to_proc
is called and the result, which must be an instance of Proc, is
passed to the method instead.

That’s very true and accurate. Thanks for the clarification. My
original intent was to say “You can [pass] a Proc object into a block
[argument] with the & prefix.” The type of the object doesn’t change,
just the passing semantics. And, “In fact, you can turn any object
into a [Proc with block argument semantics] with & and a properly
defined to_proc method.” Careless terminology and lack of
proofreading, my apologies.

Jacob F.