Blocks, eval and named parameters

D

Dan Doel

Hello,

So I was reading the brief discussion on named parameters in the
gigantic troll-fueled thread (forward
note, the hash option wasn't discussed, and I do know about it, so I
don't need to be lectured :) ), and I
saw the example of named parameters in a constructor like so:

class Foo
attr_accessor :foo, :bar
def initialize
...
yield self if block_given?
end
end

Foo.new { |obj| obj.foo = 5; obj.bar = 6 }

And someone liked it. However, this isn't really any better than:

obj = Foo.new
obj.foo = 5
obj.foo = 6

Unless you make the accessors private, in which case I think you need to
instance_eval the block.

So, I got to thinking of a way to possibly use a block to assign to
local variables. For example,
thinking of the up-and-coming scoping rule changes, maybe one could do:

class Foo
def initialize(&blk)
if blk
instance_eval &blk
end

@height = height
end
end

Foo.new do height = 5 end

However, then I thought, perhaps this already works like so:

class Foo
def initialize(height=nil, &blk)
if blk then instance_eval &blk end
@height = height
end
end

Since height will be defined as a local variable, and should propogate
out. However, instance_eval
doesn't work this way, so I doubt that it will work with the new scoping
rules.

So, finally for my question:

instance_eval, class_eval and module_eval all optionally take code
blocks to evaluate in a certain
context. However, eval itself only takes a string. Is there, or will
there ever be a way to evaluate
a code block with an arbitrary binding object/in an arbitrary context,
so that something like the
above will work? I suppose a block used in such a way is no longer a
closure, but it could be
an interesting addition to Proc's (note, I'm not sure how much utility
it would have outside this
example).

Until then, I think the closest I can come to named parameters using
blocks is:

class Foo
def initialize(&blk)
if blk
bnd = blk.call
@height = eval "height", bnd
end
end
end

Foo.new do height = 6; binding end

Then again, writing to allow:

Foo.new:)height => 6)

Isn't terribly hard, looks fine, and allows you to still pass a block
for other purposes if you need it,
so I don't think things should be changed merely for this example's sake.

Anyhow, any thoughts on all this? Thanks in advance for the stuff I'll
probably learn from any discussion
that ensues.

- Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top