A block is a syntactical construct, not an object. A Proc is the
object-ized form of a block. If you want to do something on the block,
you need to turn it into an object first.

An analogy might be that the string "def" is a syntactical construct
that creates a method, but it is not itself an object. You can't write
"def.(...)" and have it be meaningful in this context.

> So . . . how does one send a message to the block before it is passed as
> an argument? Is that even possible?

You could make it a Proc first and pass that instead. For example, say
you have a method which passes some arguments to a block:

======
> def execute(*args, &block); yield *args if block; end
 => nil

> execute(1, 2, 3) { |*args| puts "args are: #{args.inspect}" }
args are: [1, 2, 3]
 => nil
======

Instead of supplying the block, you could pass a block argument:

======
> printer = lambda { |*args| puts "args are: #{args.inspect}" }
 => #<Proc:0x0000000125eeb8@(irb):12 (lambda)>

> execute(1, 2, 3, &printer)
args are: [1, 2, 3]
======

Since `printer` is an object, you can call whatever methods you'd like
on it before passing it as a block. Of course, you still need to wind
up with something that looks like a block, or else the `yield` won't
work. For example, you might have a Proc that creates `printers` for
you:

======
> printer_factory = lambda { |message_prefix| lambda { |*args| puts "#{message_prefix}: #{args.inspect}" } }
 => #<Proc:0x000000011f9f90@(irb):17 (lambda)>
======

Now we can ask this Proc to create a printer for us, which we'll then
pass into `execute` as a block argument:

======
> execute(1, 2, 3, &printer_factory.("the arguments to this printer are"))
the arguments to this printer are: [1, 2, 3]
======

Make sense?

~ jf
--
John Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: http://stackoverflow.com/users/75170/



On Sun, Jul 3, 2011 at 10:12, Chad Perrin <code / apotheon.net> wrote:
> Stop me if I'm making any unwarranted assumptions here:
>
> Blocks are basically just a special kind of object passed to a method in
> Ruby -- aren't they?
>
> That makes them objects -- right?
>
> So . . . how does one send a message to the block before it is passed as
> an argument? Is that even possible?
>
> I ask based on curiosity and a desire to better understand the language,
> rather than as any kind of need to solve a real-world problem.
>
> --
> Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]
>