Re: Passing a named function instead of a code block?
- From: Christopher Dicely <cmdicely@xxxxxxxxx>
- Date: Sun, 22 Mar 2009 03:16:25 -0500
On 3/21/09, 7stud -- <bbxx789_05ss@xxxxxxxxx> wrote:
James Coglan wrote:
2009/3/20 7stud -- <bbxx789_05ss@xxxxxxxxx>
Yes, it probably looks that way. To see the difference it helps to knowpreceded by some symbol.&method(:square1)grab a method as an object without calling it, we need to use
how
Ruby is parsed. :square1 is an atomic unit representing the symbol whose
name is 'square1'. ":" is not an operator, it is part of the syntax for
symbols. However, "&" is an operator responsible for casting between
procs
and blocks. The expression '&square1' should be read '&( square1 )',
that is
we call square1 and cast the result of that using '&'. The same applies
to
'method'. 'method' is a method that takes a symbol/string and returns
the
Method object with that name in the current scope. 'method(square1)'
would
be interpreted as a call to square1, passing the result to 'method'.
So, '&square1' throws an error because you're calling a method with
insufficient arguments. '&:square1' would try to cast a symbol to a
proc,
which if you're using ActiveSupport would return the block { |object|
object.square1 }.
'&square2' is fine as square2 is just a variable referring to a proc.
Likewise, '&method(:square1)' is fine because method(:square1) is a
Method
object, which can be cast to a block.
Thanks for the explanation. You said that (&) casts between block and
Procs. But (&) also appears to be casting a Method to a block in this
line:
puts c.collect(&method(:fib))
Actually, its casting a Method to a Proc (by calling to_proc on it)
and then treating the proc as a block. To see that's what is
happening, try this:
class Integer
def to_proc
Proc.new { self }
end
end
(1..10).map(&1)
Can (&) cast a block to a Method?
No. & in a method call always treats a the given proc as a block given
to the method while & in a method definition always makes a block
given to the method as a Proc. Its probably best not to think of this
as "casting" except insofar as the first one "casts" to a proc first
by calling to_proc; blocks aren't objects, and if you do this:
def consume(object=nil)
if block_given? then yield else object end
end
p = lambda { puts "foo!" }
consume(&p)
You don't get the results you' d get if an object of the
(non-existent) class "Block" was passed to consume, you get the
results you would get if consume was called with a block. So thinking
of & as "casting" an argument to a different class in the method call
is misleading.
.
- References:
- Passing a named function instead of a code block?
- From: Paul Jungwirth
- Re: Passing a named function instead of a code block?
- From: Matthias Reitinger
- Re: Passing a named function instead of a code block?
- From: 7stud --
- Re: Passing a named function instead of a code block?
- From: James Coglan
- Re: Passing a named function instead of a code block?
- From: 7stud --
- Re: Passing a named function instead of a code block?
- From: James Coglan
- Re: Passing a named function instead of a code block?
- From: 7stud --
- Passing a named function instead of a code block?
- Prev by Date: Re: Passing a named function instead of a code block?
- Next by Date: Re: Run a Ruby script (.rbw) from a dock shortcut in Mac OS X (Leopard)?
- Previous by thread: Re: Passing a named function instead of a code block?
- Next by thread: Re: Passing a named function instead of a code block?
- Index(es):
Relevant Pages
|