Is Passing a Binding with Parameters Possible?

Discussion in 'Ruby' started by John Sikora, Sep 3, 2009.

  1. John Sikora

    John Sikora Guest

    Does anyone know how to pass a binding using parameters instead of a
    code block? Is it even possible?

    For various reasons (primarily syntactic sugar implementation), I need
    to eval a string in one method in the scope of another method. The
    following is a simplified version of the code (which works):


    def called_method(*parameters, &code_block) # code_block handler
    ignored.
    parameters.each do |parameter|
    eval(parameter, code_block.binding)
    end
    end

    def calling_method
    a = 3
    string_to_evaluate = 'puts a'
    called_method(string_to_evaluate){}
    end

    calling_method # => 3


    Obviuosly, this requires a code block for 'called_method'. In the actual
    code, whenever eval is used, parameters are always present. Code blocks
    are optional. So when a code block is not needed, the empty code block
    has to be included.

    No big deal, but it would be nice to be able to use the parameters to
    pass the binding (since they are always present when eval is used). Such
    as:


    def called_method(*parameters, &code_block) # code_block handler
    ignored.
    parameters.each do |parameter|
    eval(parameter, parameters.binding)
    end
    end

    def calling_method
    a = 3
    string_to_evaluate = 'puts a'
    called_method(string_to_evaluate)
    end

    calling_method # => in 'called_method' private method 'binding'
    called...


    So I guess .binding is a private method for objects other than code
    blocks, in this case an Array. If I change 'parameters.binding' to
    'binding', it (of course) does not give the right binding, resulting in
    variable 'a' being undefined. I have tried some other code snippets that
    I thought might work, but to no avail.

    I know a binding could be created inside of calling_method and it could
    be could be passed, but the way it is now with the empty braces is
    easier, which is the point of syntactic sugar.

    Can it be made even easier by passing the binding 'automatically' with
    the parameters instead of a code block?

    John S.
    --
    Posted via http://www.ruby-forum.com/.
     
    John Sikora, Sep 3, 2009
    #1
    1. Advertising

  2. John Sikora

    7stud -- Guest

    John Sikora wrote:
    >
    > Obviuosly, this requires a code block for 'called_method'. In the actual
    > code, whenever eval is used, parameters are always present. Code blocks
    > are optional. So when a code block is not needed, the empty code block
    > has to be included.
    >
    > No big deal, but it would be nice to be able to use the parameters to
    > pass the binding


    How about:

    def called_method(*parameters, &code_block)
    if block_given?
    #do something

    elsif
    b = parameters[-1]
    params = parameters[0..-2]

    params.each do |param|
    eval(param, b)
    end

    end
    end

    def calling_method
    a = 3
    string_to_evaluate = 'puts a'
    called_method(string_to_evaluate, binding)
    end

    calling_method # => 3

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Sep 4, 2009
    #2
    1. Advertising

  3. John Sikora

    7stud -- Guest

    Or this:

    class Parameters
    def initialize(bind_ing, *parameters)
    @binding = bind_ing
    @parameters = parameters
    end

    def each
    @parameters.each {|param| yield [param, @binding]}
    end

    end

    def called_method(parameters, &code_block)
    if block_given?
    #do something

    elsif
    parameters.each do |param, bind_ing|
    eval(param, bind_ing)
    end

    end
    end

    def calling_method
    a = 3
    b = 4
    eval_str1 = 'puts a'
    eval_str2 = 'puts b'
    params = Parameters.new(binding, eval_str1, eval_str2)
    called_method(params)
    end

    calling_method # => 3, 4

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Sep 4, 2009
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

    I like lmgtfy:

    http://lmgtfy.com/?q=Binding of_caller

    Kind regards,
    Samuel

    On 4/09/2009, at 9:03 AM, John Sikora wrote:

    > Does anyone know how to pass a binding using parameters instead of a
    > code block? Is it even possible?
    >
    > For various reasons (primarily syntactic sugar implementation), I need
    > to eval a string in one method in the scope of another method. The
    > following is a simplified version of the code (which works):
    >
    >
    > def called_method(*parameters, &code_block) # code_block handler
    > ignored.
    > parameters.each do |parameter|
    > eval(parameter, code_block.binding)
    > end
    > end
    >
    > def calling_method
    > a = 3
    > string_to_evaluate = 'puts a'
    > called_method(string_to_evaluate){}
    > end
    >
    > calling_method # => 3
    >
    >
    > Obviuosly, this requires a code block for 'called_method'. In the
    > actual
    > code, whenever eval is used, parameters are always present. Code
    > blocks
    > are optional. So when a code block is not needed, the empty code block
    > has to be included.
    >
    > No big deal, but it would be nice to be able to use the parameters to
    > pass the binding (since they are always present when eval is used).
    > Such
    > as:
    >
    >
    > def called_method(*parameters, &code_block) # code_block handler
    > ignored.
    > parameters.each do |parameter|
    > eval(parameter, parameters.binding)
    > end
    > end
    >
    > def calling_method
    > a = 3
    > string_to_evaluate = 'puts a'
    > called_method(string_to_evaluate)
    > end
    >
    > calling_method # => in 'called_method' private method 'binding'
    > called...
    >
    >
    > So I guess .binding is a private method for objects other than code
    > blocks, in this case an Array. If I change 'parameters.binding' to
    > 'binding', it (of course) does not give the right binding, resulting
    > in
    > variable 'a' being undefined. I have tried some other code snippets
    > that
    > I thought might work, but to no avail.
    >
    > I know a binding could be created inside of calling_method and it
    > could
    > be could be passed, but the way it is now with the empty braces is
    > easier, which is the point of syntactic sugar.
    >
    > Can it be made even easier by passing the binding 'automatically' with
    > the parameters instead of a code block?
    >
    > John S.
    > --
    > Posted via http://www.ruby-forum.com/.
    >
     
    Space Ship Traveller, Sep 4, 2009
    #4
  5. John Sikora

    John Sikora Guest

    7stud -- wrote:
    > Or this:
    >


    > def calling_method
    > a = 3
    > b = 4
    > eval_str1 = 'puts a'
    > eval_str2 = 'puts b'
    > params = Parameters.new(binding, eval_str1, eval_str2)
    > called_method(params)
    > end
    >
    > calling_method # => 3, 4


    7stud,

    I was hoping to be able to do it w/o having to include the binding (in
    any form)in calling_method. In other words, the binding could be
    'attached' to the parameters similar to a code block.

    Thanks,
    John S.
    --
    Posted via http://www.ruby-forum.com/.
     
    John Sikora, Sep 4, 2009
    #5
  6. John Sikora

    John Sikora Guest

    Space Ship Traveller wrote:
    > I like lmgtfy:
    >
    > http://lmgtfy.com/?q=Binding of_caller
    >
    > Kind regards,
    > Samuel



    SST,

    Thanks for the link. No one has ever accused me of being particularly
    adept at conducting a web search.

    Unfortunately, I feel even more ignorant because I cannot get the code
    to work. At first I tried adapting the code in my post to use
    Binding.of_caller. When it did not work, I tried the example code from
    the link:


    require
    'c:/Ruby/lib/ruby/gems/1.8/gems/extensions-0.6.0/lib/extensions/binding'

    def inc_counter
    Binding.of_caller do |b|
    eval("counter += 1", b)
    end
    end

    counter = 0
    inc_counter
    inc_counter
    puts counter


    I get an error message that says: in 'inc_counter': undefined method '+'
    for nil:NilClass. So it is not getting the correct binding. Debugging
    shows that Binding.of_caller returned a binding to inc_counter.

    The code in the require file matches the source code of of_caller in the
    link, so at least I know that is right.

    Is there something obvious am I doing wrong? I am running Ruby 1.8.6 on
    Windows. I will try to educate myself by studying the source code to
    figure out what is wrong, but it will take some time (if I ever get
    there).

    Thanks,
    John S.
    --
    Posted via http://www.ruby-forum.com/.
     
    John Sikora, Sep 4, 2009
    #6
  7. On 9/4/09, John Sikora <> wrote:
    > Space Ship Traveller wrote:
    >> I like lmgtfy:
    >>
    >> http://lmgtfy.com/?q=Binding of_caller

    >
    > Thanks for the link. No one has ever accused me of being particularly
    > adept at conducting a web search.
    >
    > Unfortunately, I feel even more ignorant because I cannot get the code
    > to work. At first I tried adapting the code in my post to use


    Binding.of_caller is really a hack... Don't use it. You're better off
    passing a binding explicitly, like 7stud says, or implicitly in a
    block, like you had originally.
     
    Caleb Clausen, Sep 5, 2009
    #7
  8. John Sikora

    John Sikora Guest

    Caleb Clausen wrote:
    > On 9/4/09, John Sikora <> wrote:
    >> Space Ship Traveller wrote:
    >>> I like lmgtfy:
    >>>
    >>> http://lmgtfy.com/?q=Binding of_caller

    >>
    >> Thanks for the link. No one has ever accused me of being particularly
    >> adept at conducting a web search.
    >>
    >> Unfortunately, I feel even more ignorant because I cannot get the code
    >> to work. At first I tried adapting the code in my post to use

    >
    > Binding.of_caller is really a hack... Don't use it. You're better off
    > passing a binding explicitly, like 7stud says, or implicitly in a
    > block, like you had originally.


    Caleb,

    Thanks, I'll just leave it as is.

    John S.
    --
    Posted via http://www.ruby-forum.com/.
     
    John Sikora, Sep 8, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jordan
    Replies:
    2
    Views:
    2,560
    Jordan
    Feb 10, 2004
  2. David Freeman
    Replies:
    4
    Views:
    3,427
    David Freeman
    Nov 9, 2004
  3. Amit
    Replies:
    6
    Views:
    13,892
    Assimalyst
    Oct 24, 2006
  4. Ramon F Herrera
    Replies:
    8
    Views:
    499
    Pascal J. Bourguignon
    Sep 13, 2009
  5. David Freeman
    Replies:
    4
    Views:
    220
    David Freeman
    Nov 9, 2004
Loading...

Share This Page