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
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:
John,
although I was not original question author, wanted to thank you for
that great explanation and example.
stephenb
···
2011/7/3 John Feminella <johnf@bitsbuilder.com>
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
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:
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 ]
>
John,
although I was not original question author, wanted to thank you for
that great explanation and example.
Just one point of nitpicking:
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
I'd rather use these in pairs because the conversion of a block to an
accessible object has some overhead:
- block_given? and yield
- &b and b / b.call
So either
def execute(*args)
yield *args if block_given?
end
or
def execute(*args, &block)
block[*args] if block
end
respectively
def execute(*args, &block)
block.call(*args) if block
end
Usually you only need the form with &block if you need to store the
block or pass it on to another method, e.g.
def foo
yield 123
end
def bar(&b)
foo(&b) # pass on
end
bar {|x| p x} # will print 123
Kind regards
robert
···
On Sun, Jul 3, 2011 at 5:15 PM, Stephen Boesch <javadba@gmail.com> wrote:
That is a fair point, Robert. I didn't use block_given? because I
wanted to show that indeed, `block` is an object by the time you can
see it in the method. Using "if block_given?" might not have made that
clear, but I thought that writing "if block" makes it unambiguous that
`block` is a real object with its own semantics.
On Mon, Jul 4, 2011 at 11:54, Robert Klemme <shortcutter@googlemail.com> wrote:
On Sun, Jul 3, 2011 at 5:15 PM, Stephen Boesch <javadba@gmail.com> wrote:
John,
although I was not original question author, wanted to thank you for
that great explanation and example.
Just one point of nitpicking:
2011/7/3 John Feminella <johnf@bitsbuilder.com>
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
I'd rather use these in pairs because the conversion of a block to an
accessible object has some overhead:
- block_given? and yield
- &b and b / b.call
So either
def execute(*args)
yield *args if block_given?
end
or
def execute(*args, &block)
block[*args] if block
end
respectively
def execute(*args, &block)
block.call(*args) if block
end
Usually you only need the form with &block if you need to store the
block or pass it on to another method, e.g.
Jeremy, that was an excellent synopsis of the functionality of blocks,
procs, methods and lambdas. I'm starting to get my head around
anonymous functions, closures and currying.
On Mon, Jul 4, 2011 at 1:23 PM, Joe Peric <peric.joe@gmail.com> wrote:
Jeremy, that was an excellent synopsis of the functionality of blocks,
procs, methods and lambdas. I'm starting to get my head around
anonymous functions, closures and currying.