Forum: Ruby variables to call methods in ruby...

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Harnish (Guest)
on 2007-06-25 02:43
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.<testfunc>
-----------------

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
Adam B. (Guest)
on 2007-06-25 02:49
(Received via mailing list)
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
Tim H. (Guest)
on 2007-06-25 02:50
(Received via mailing list)
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)
(Guest)
on 2007-06-25 03:51
(Received via mailing list)
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
Peter C. (Guest)
on 2007-06-25 03:58
(Received via mailing list)
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"(tm) 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/
Adam B. (Guest)
on 2007-06-25 04:46
(Received via mailing list)
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
unknown (Guest)
on 2007-06-25 05:42
(Received via mailing list)
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 :-) to a Message object, they'll end up calling the new
send.


David
Adam B. (Guest)
on 2007-06-25 06:11
(Received via mailing list)
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 :-) to a Message object, they'll end up calling the new
> send.


Doh! Good call.  Time to kick my double underscore aversion ;)

-Adam
Peter C. (Guest)
on 2007-06-25 06:13
(Received via mailing list)
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/
This topic is locked and can not be replied to.