Hello,
Let's say that I have created a proc like:
a = proc{ puts x } (NOT! a = proc{ |x| puts x })
In this case, x within the scope of the proc does not exist and proc 'a'
is unable to receive an argument to set it...
If I wanted to take proc 'a' and create another proc, which did include
arguments...
In fact, lets say I just wanted to grab an existing proc, modify the
parameters to include |*args|, knowing that within the existing proc, I am
grabbing my passed variables from the args array, even though they, at that
point, don't exist...
I did find the 'parameters' method on Proc and I found that when a proc
has arity of 0, parameters is an empty array, and then depending on the
argument, parameters will return something like [ [:opt, :x], [:opt, :y] ]
for |x, y| or [ [:rest, :args] ] for |*args|...
However, parameters, while it certain LOOKS like it is taking the values
if I pass (<<) the appropriate values to it, they will not actually store.
The array instance returned by #parameters is just for your information.
Mutating it has not effect because clearly, you're just getting a new array
instance each time you call #parameters (likely generated from internal
state you don't have direct access to):
irb(main):001:0> a = proc { puts x }
=> #<Proc:0x007f95891baca8@(irb):1>
irb(main):002:0> a.parameters.object_id
=> 70140113542620
irb(main):003:0> a.parameters.object_id
=> 70140113536380
There is not way that I'm aware of to posthumously mutate a Proc. At best,
you can #curry the proc to get a new proc, but that's not a mutation of the
original proc, just a way to "wrap" it.
I also played around a little bit with grabbing the binding of the proc
without parameters and then trying to create the required variables within
that binding, but I didn't try too hard which is probably why it didn't
work, because in theory, that should be doable.
Yeah, with the new #local_variable_set and #local_variable_get, it does
seem like it'd work to a.local_variable_set(:x, "hello world") but as you
figured out, it doesn't, even though a.local_variable_get(:x) will indicate
the set _did_ in fact work.
Is what I am attempting to do possible? Or is there a work-around that
isn't *too* hacky?
I think someone more knowledgeable than I would have to explain exactly why
Binding#local_variable_set isn't designed to solve problems such as this
(I'm sure there's either a good technical, difficulty of implementation or
even language design reason). However, I do know it's not just that you're
doing it wrong, it just doesn't support that behavior:
From the example code in the doc for that method, you can see that even
though Binding#local_variable_set _works_ to set a variable in a binding,
actual code in the same scope that tries to reference said local variable
still raises a NameError.
···
On Wed, Jul 2, 2014 at 8:18 AM, Daniel Marvin <danielmarvin09@gmail.com> wrote:
Thanks in advance,
Daniel
--
Kendall Gifford
zettabyte@gmail.com