Variables to call methods in ruby


#1

Hi,

This is Harnish. I was just wondering if I could call methods using
variables?

As for example:


testfunc = “func”

class Test
def self.func
puts “hello there…!”
end
end

Test.

Essentially I want to call Test.func; but “func” lies in the variable
testfunc; is it possible for me to invoke Test.func using variable
testfunc? If yes, how? Any ideas, greatly appreciated.

Regards,
Harnish


#2

On 6/24/07, Harnish removed_email_address@domain.invalid wrote:

testfunc; is it possible for me to invoke Test.func using variable
testfunc? If yes, how? Any ideas, greatly appreciated.

You can use send:

testfunc = “func”

class Test
def self.func
puts “hello there…!”
end
end

Test.send testfunc


#3

Harnish wrote:

Essentially I want to call Test.func; but “func” lies in the variable
testfunc; is it possible for me to invoke Test.func using variable
testfunc? If yes, how? Any ideas, greatly appreciated.

Check out the “send” method:

var = “func”
obj.send(var, args)


#4

On Jun 24, 5:48 pm, Tim H. removed_email_address@domain.invalid wrote:

Harnish wrote:

Essentially I want to call Test.func; but “func” lies in the variable
testfunc; is it possible for me to invoke Test.func using variable
testfunc? If yes, how? Any ideas, greatly appreciated.

Check out the “send” method:

var = “func”
obj.send(var, args)

I’ve always used it without the underscores:

var = “func”
obj.send “func”, an_arg


#5

On 6/25/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

I’ve always used it without the underscores:

You can, but in case you’re wondering the whys and wherefores of all
this… it’s possible to easily change the “send” method on a class
with anyone noticing… this could cause "Bad Things"™ to happen.

It’s possible to redefine send too, but a warning is given and
it’s generally considered bad form to redefine, delete, or otherwise
modify methods using the x naming convention. You’ll notice
classes like BlankSlate (
http://onestepback.org/index.cgi/Tech/Ruby/BlankSlate.rdoc ) take this
into account:

class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end

Cheers,
Peter C.
http://www.rubyinside.com/


#6

On 6/24/07, Peter C. removed_email_address@domain.invalid wrote:

it’s generally considered bad form to redefine, delete, or otherwise
modify methods using the x naming convention. You’ll notice
classes like BlankSlate (
http://onestepback.org/index.cgi/Tech/Ruby/BlankSlate.rdoc ) take this
into account:

class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end

I see your point, it just seems like using send breaks
encapsulation.
If a class is re-defining send for some reason, the user probably
shouldn’t
have to know/care about it.

I suppose if the proxy is adding some extra methods ( is_proxy?() ) then
send would be a better choice. But then again, unless you add that
to
everything, you’d have to use a respond_to? – starting to get pretty
ugly.
Can you think of any cases that show why always using send is both
necessary and clean?

And of course in the simple proxy example, using send doesn’t really
make a difference.

class BlankSlate
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end

class Proxy < BlankSlate
def initialize obj
@obj = obj
end
def method_missing msg , *args , &block
puts “proxying #{msg}…”
@obj.send msg , *args , &block
end
end

str = Proxy.new “hello”
puts ( str.send(:size) == str.send(:size)) # => true

-Adam


#7

Hi –

On Mon, 25 Jun 2007, Adam B. wrote:

I see your point, it just seems like using send breaks encapsulation.
If a class is re-defining send for some reason, the user probably shouldn’t
have to know/care about it.

I suppose if the proxy is adding some extra methods ( is_proxy?() ) then
send would be a better choice. But then again, unless you add that to
everything, you’d have to use a respond_to? – starting to get pretty ugly.
Can you think of any cases that show why always using send is both
necessary and clean?

It’s really more for cases where ‘send’ is used for something totally
different:

class Message
def send
Net::SMTP.open …

end
end

If someone wants to send (in the original sense) a message (in the
original sense :slight_smile: to a Message object, they’ll end up calling the new
send.

David


#8

On 6/24/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

If someone wants to send (in the original sense) a message (in the
original sense :slight_smile: to a Message object, they’ll end up calling the new
send.

Doh! Good call. Time to kick my double underscore aversion :wink:

-Adam


#9

On 6/25/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

On Mon, 25 Jun 2007, Adam B. wrote:

Can you think of any cases that show why always using send is both
necessary and clean?

It’s really more for cases where ‘send’ is used for something totally
different:

David illustrates it better than I did, but the basic “rule” I tend to
take away is that “send” is, effectively, guaranteed to do what I
think it will (I’ll see a warning if it doesn’t)… whereas “send”
might not. Such concerns aren’t that important if you’re working on
classes you’re familiar with, however, or if methods aren’t being
called on dynamically-chosen classes you have little control over.

Cheers,
Peter C.
http://www.rubyinside.com/