assigning constant as an unbound dynamic method

Discussion in 'Ruby' started by Scott Strattner, Dec 12, 2006.

  1. Disclaimer: I am new to Ruby, and am not a professional programmer. I
    work in Network Support, and have used Perl in the past for various
    scripting tasks. On a lark I picked up the 'pickaxe' book and wanted to
    try my hand at a Ruby program which will use SNMP to grab various stats
    from some network devices. I am using the SNMP module
    (http://snmplib.rubyforge.org/) and it's working fine.

    In this module you can do a 'get' or a 'walk' on a device - basically
    the former grabs a single MIB value while the latter goes down the MIB
    tree to grab multiple values at once. I wanted to be able to dynamically
    call either get or walk depending on how my method was called. I know I
    could get around this by just coding two separate methods or the like,
    but I wanted to try to use dynamic method calls which seems to me to be
    more eloquent.

    Looking at the examples in the book (p. 408 in 2nd edition), it appears
    I can do a <Class>.instance_method:)<method name>) assignment, then bind
    that to a particular object, and then run call. For instance (from
    book):

    str = "cat"
    ulen = String.instance_method:)length)
    blen = ulen.bind(str)
    blen.call -> 3

    How I'd like to work that in my program is to define two constants
    (within a class called Device), which correspond to the two
    instance_methods:

    class Device
    ....
    GET = SMTP::Manager.instance_method:)get)
    WALK = SMTP::Manager.instance_method:)walk)

    and then:

    def query_device(mibval,type=GET,mib=RFC1213)
    data = []
    response = NOTSET
    begin
    SNMP::Manager.open:)Host => @ip.to_s,
    :Community => @comm) do
    |manager|
    manager.load_module(mib) unless (mib == RFC1213)
    mngr = type.bind(manager)
    response = mngr.call(mibval)
    end
    rescue
    etc.....
    end

    But when I try running this, I get the following error:

    uninitialized constant Device::SMTP (NameError)

    It appears to be adding my class onto the method name. I do have the
    necessary "require" in place (before I define the constants), and the
    SNMP::Manager.open command worked fine (before I make changes to get
    dynamic method calls to work). So I'm not sure why it's adding my class
    name here but it doesn't try to do that under query_device.

    If I can't figure it out I will probably just go with passing a
    parameter to query_device and use 'catch' to determine what method to
    call, but if someone could give me a clue as to what I'm doing wrong (or
    if what I'm trying to do is even possible), I'd appreciate it. Thanks.

    --
    Posted via http://www.ruby-forum.com/.
     
    Scott Strattner, Dec 12, 2006
    #1
    1. Advertising

  2. Scott Strattner

    Guest

    Scott Strattner wrote:
    > Disclaimer: I am new to Ruby, and am not a professional programmer. I
    > work in Network Support, and have used Perl in the past for various
    > scripting tasks. On a lark I picked up the 'pickaxe' book and wanted to
    > try my hand at a Ruby program which will use SNMP to grab various stats
    > from some network devices. I am using the SNMP module
    > (http://snmplib.rubyforge.org/) and it's working fine.
    >
    > In this module you can do a 'get' or a 'walk' on a device - basically
    > the former grabs a single MIB value while the latter goes down the MIB
    > tree to grab multiple values at once. I wanted to be able to dynamically
    > call either get or walk depending on how my method was called. I know I
    > could get around this by just coding two separate methods or the like,
    > but I wanted to try to use dynamic method calls which seems to me to be
    > more eloquent.
    >
    > Looking at the examples in the book (p. 408 in 2nd edition), it appears
    > I can do a <Class>.instance_method:)<method name>) assignment, then bind
    > that to a particular object, and then run call. For instance (from
    > book):
    >
    > str = "cat"
    > ulen = String.instance_method:)length)
    > blen = ulen.bind(str)
    > blen.call -> 3
    >
    > How I'd like to work that in my program is to define two constants
    > (within a class called Device), which correspond to the two
    > instance_methods:
    >
    > class Device
    > ....
    > GET = SMTP::Manager.instance_method:)get)
    > WALK = SMTP::Manager.instance_method:)walk)
    >
    > and then:
    >
    > def query_device(mibval,type=GET,mib=RFC1213)
    > data = []
    > response = NOTSET
    > begin
    > SNMP::Manager.open:)Host => @ip.to_s,
    > :Community => @comm) do
    > |manager|
    > manager.load_module(mib) unless (mib == RFC1213)
    > mngr = type.bind(manager)
    > response = mngr.call(mibval)
    > end
    > rescue
    > etc.....
    > end
    >
    > But when I try running this, I get the following error:
    >
    > uninitialized constant Device::SMTP (NameError)
    >
    > It appears to be adding my class onto the method name. I do have the
    > necessary "require" in place (before I define the constants), and the
    > SNMP::Manager.open command worked fine (before I make changes to get
    > dynamic method calls to work). So I'm not sure why it's adding my class
    > name here but it doesn't try to do that under query_device.
    >
    > If I can't figure it out I will probably just go with passing a
    > parameter to query_device and use 'catch' to determine what method to
    > call, but if someone could give me a clue as to what I'm doing wrong (or
    > if what I'm trying to do is even possible), I'd appreciate it. Thanks.
    >
    > --
    > Posted via http://www.ruby-forum.com/.


    You can just use the "send" method, which is defined in the base class
    Object from which all other classes are derived, e.g., mngr.send:)get)
    or mngr.send:)walk). So, in your case, pass the symbol :get or :walk
    as your type argument and then send() that to your mngr. See the pic
    axe pg. 574. Hope this helps some.

    Ken
     
    , Dec 12, 2006
    #2
    1. Advertising

  3. Scott Strattner

    Tom Werner Guest

    Scott Strattner wrote:
    > Looking at the examples in the book (p. 408 in 2nd edition), it appears
    > I can do a <Class>.instance_method:)<method name>) assignment, then bind
    > that to a particular object, and then run call. For instance (from
    > book):
    >
    > str = "cat"
    > ulen = String.instance_method:)length)
    > blen = ulen.bind(str)
    > blen.call -> 3
    >
    > How I'd like to work that in my program is to define two constants
    > (within a class called Device), which correspond to the two
    > instance_methods:
    >
    > class Device
    > ....
    > GET = SMTP::Manager.instance_method:)get)
    > WALK = SMTP::Manager.instance_method:)walk)
    >
    > and then:
    >
    > def query_device(mibval,type=GET,mib=RFC1213)
    > data = []
    > response = NOTSET
    > begin
    > SNMP::Manager.open:)Host => @ip.to_s,
    > :Community => @comm) do
    > |manager|
    > manager.load_module(mib) unless (mib == RFC1213)
    > mngr = type.bind(manager)
    > response = mngr.call(mibval)
    > end
    > rescue
    > etc.....
    > end
    >
    > But when I try running this, I get the following error:
    >
    > uninitialized constant Device::SMTP (NameError)
    >
    > It appears to be adding my class onto the method name. I do have the
    > necessary "require" in place (before I define the constants), and the
    > SNMP::Manager.open command worked fine (before I make changes to get
    > dynamic method calls to work). So I'm not sure why it's adding my class
    > name here but it doesn't try to do that under query_device.
    >

    Try prefixing with ::, that will get you back to the root scope:

    GET = ::SMTP::Manager.instance_method:)get)

    Tom
     
    Tom Werner, Dec 13, 2006
    #3
    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. Farshid Lashkari
    Replies:
    2
    Views:
    398
    Paolino
    Jul 28, 2005
  2. arotem
    Replies:
    4
    Views:
    9,202
    arotem
    Oct 17, 2005
  3. Kevin Walzer

    Error: unbound method in Tkinter class

    Kevin Walzer, Dec 9, 2006, in forum: Python
    Replies:
    2
    Views:
    366
    Bjoern Schliessmann
    Dec 9, 2006
  4. Replies:
    2
    Views:
    583
  5. weston
    Replies:
    1
    Views:
    281
    Richard Cornford
    Sep 22, 2006
Loading...

Share This Page