Dynamic method execution problem

Discussion in 'Ruby' started by joe.yakich@gmail.com, Sep 9, 2005.

  1. Guest

    All,

    I have been trying to figure out a way to execute a series of methods,
    only 1 of which is expected to actually run without exception, in a
    particular order. I haven't figured out how to use send or Method#call,
    so I was messing with eval, but not with much success (I have problems
    with argument passing, calling the right method, and so on.)

    I have been trying this, but it doesn't quite work. (As background
    information, I'm using the Watir test library, and I want to interact
    with a web page that may have 1 of 4 different elements, each of which
    I have methods to access and use.)

    # Each item in this array is a different method name (I changed the
    names to
    # "methodn" from more useful names for the purposes of this question)
    methods = [
    "method1",
    "method2",
    "method3",
    "method4"
    ]

    # The ie variable here refers to a Watir::IE object
    begin
    my_method = methods.shift
    puts "Trying #{my_method}"
    eval "#{my_method}(ie)"
    end

    rescue UnknownObjectException
    if methods.length > 0
    retry
    else
    raise
    end

    Any suggestions? I'm new to Ruby, so perhaps there's a totally
    different approach that is the standard way to address this. (I was
    trying stuff inspired from PickAxe 2nd Ed, pg.112 and pg.407-409).

    Thanks in advance!

    Joe
     
    , Sep 9, 2005
    #1
    1. Advertising

  2. Jacob Fugal Guest

    On 9/9/05, <> wrote:
    <snip definition of methods array>
    > # The ie variable here refers to a Watir::IE object
    > begin
    > my_method =3D methods.shift
    > puts "Trying #{my_method}"
    > eval "#{my_method}(ie)"
    > end
    >=20
    > rescue UnknownObjectException
    > if methods.length > 0
    > retry
    > else
    > raise
    > end


    First, a fix... you don't want the end to the begin block until after
    the rescue, example:

    begin
    # do risky operation
    rescue
    # recover from failure
    end

    Then, translating to use send instead of eval:

    begin
    my_method =3D methods.shift
    puts "Trying #{my_method}"
    send(my_method.to_sym, ie)
    rescue UnknownObjectException
    retry unless methods.empty?
    raise
    end

    (I also changed the content of the rescue clause to something that
    flows a bit nicer for me, but this is just a style issue. What you had
    works fine)

    The send method sends the method identified by the first argument to
    the receiver (here the implicit self) with the remainder of the
    arguments.

    Myself, rather than using retry, I'd do something like this:

    methods =3D [ :method1, :method2, ... ]

    methods.find do |method|
    puts "Trying #{method}"
    begin
    send( method, ie )
    method
    rescue
    end
    end or raise "No applicable method found"

    This makes the nature of looping through the methods more explicit,
    rather than relying on a combination of .shift, .empty? and retry.

    Jacob Fugal
     
    Jacob Fugal, Sep 9, 2005
    #2
    1. Advertising

  3. Guest

    Jacob,

    Wow, that's much cleaner and clearer. It even works, too. :)

    Thank you!

    Joe
     
    , Sep 9, 2005
    #3
  4. > [snip]=20
    > begin
    > my_method =3D methods.shift
    > puts "Trying #{my_method}"
    > send(my_method.to_sym, ie)
    > rescue UnknownObjectException
    > retry unless methods.empty?
    > raise
    > end


    You don't need to convert my_method to a symbol explicitly. Just pass
    it on, and send will handle it on its own. That way you don't take on
    responsibility for argument checking of send and if somehow send is
    changed to take something that can not be represented as a symbol -
    and your code gets feeded with it - the code will continue to work.
    The send example may be silly because it's unlikely to change, but I
    think it is a general guideline not to assume too much about the
    called methods but let the called methods figure it out for
    themeselves. Also I don't think this is opposed to "fail early" but
    that would be open to some discussion by people more intelligent than
    me.

    best regards,

    Brian

    > [snip]
    >=20
    > Jacob Fugal
    >=20
    >=20



    --=20
    http://ruby.brian-schroeder.de/

    Stringed instrument chords: http://chordlist.brian-schroeder.de/
     
    Brian Schröder, Sep 10, 2005
    #4
    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. Kishor

    Dynamic Execution of Function/Proc

    Kishor, Sep 24, 2003, in forum: ASP .Net
    Replies:
    9
    Views:
    553
    Kishor
    Sep 27, 2003
  2. Jesper Sahner
    Replies:
    1
    Views:
    368
    Rhino
    Feb 1, 2005
  3. Andy Wu

    Dynamic function execution

    Andy Wu, Nov 25, 2006, in forum: Python
    Replies:
    5
    Views:
    306
    Fredrik Lundh
    Nov 26, 2006
  4. Nikhil

    Dynamic tracing of C code execution

    Nikhil, May 12, 2006, in forum: C Programming
    Replies:
    5
    Views:
    1,633
    Frank Pittel
    May 16, 2006
  5. Ggianks
    Replies:
    1
    Views:
    319
    Goran Pusic
    Aug 19, 2010
Loading...

Share This Page