From: coachhilton@... Date: 2006-12-13T08:50:14+09:00 Subject: Re: assigning constant as an unbound dynamic method 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 .instance_method(:) 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