[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

assigning constant as an unbound dynamic method

Scott Strattner

12/12/2006 11:21:00 PM

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.ruby...) 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-....

2 Answers

coachhilton

12/12/2006 11:47:00 PM

0


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.ruby...) 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-....

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

Tom Werner

12/13/2006 7:49:00 PM

0

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