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