By BuddyJoe


2009-09-10 20:10:26 8 Comments

How can I do what they are talking about here, but in Ruby?

How would you do the function on an object? and how would you do a global function (see jetxee's answer on the post mentioned)?

EXAMPLE CODE:

event_name = "load"

def load()
  puts "load() function was executed."
end

def row_changed()
  puts "row_changed() function was executed."
end 

#something here to see that event_name = "load" and run load()

UPDATE: How do you get to the global methods? or my global functions?

I tried this additional line

puts methods

and load and row_change where not listed.

4 comments

@Colin Gravill 2009-09-10 20:17:27

To call functions directly on an object

a = [2, 2, 3]
a.send("length")
# or
a.public_send("length")

which returns 3 as expected

or for a module function

FileUtils.send('pwd')
# or
FileUtils.public_send(:pwd)

and a locally defined method

def load()
    puts "load() function was executed."
end

send('load')
# or
public_send('load')

Documentation:

@BuddyJoe 2009-09-10 21:15:11

+1 That works. This may be a dumb follow up ... but how come I can't find the word send in the Ruby source at - C:\ruby\lib\ruby\1.8\fileutils.rb? Thought I would find the send function in there.

@BuddyJoe 2009-09-10 21:15:57

I was curious to what it was doing under the hood.

@Colin Gravill 2009-09-10 21:44:58

It's defined on object - ruby-doc.org/core/classes/Object.html#M000332 I picked a random function for interest value.

@BuddyJoe 2009-09-10 21:50:38

Interesting because before I read your answer twice, and fully grok'd it I ran the FileUtils.send("load") and it ran my function. so if I understand this correctly by creating functions in "global" am I adding the methods onto the root object? or not?

@Colin Gravill 2009-09-10 21:50:45

Good on you for looking stuff up in the source! :)

@Colin Gravill 2009-09-10 21:59:13

I think they are being created as private method on the root object so global method might not be the best name for them

@Chuck 2009-09-10 22:09:48

@Tyndall: Maybe it would be helpful not to think of them as functions. The only true functions in Ruby are created like lambda {|x| x+1}. Everything else is a method of some object. When you open an empty Ruby file and type def foo(bar), you are defining a private method of the class Object. It will be available everywhere (since everything is an Object), but more specific classes are free to override it as well.

@Tim Snowhite 2010-04-20 14:48:58

@tyndall, even lambda isn't really a function, it creates a Proc object. There was discussion about this here: stackoverflow.com/questions/1933390/…

@user2503775 2015-06-09 14:28:31

What if I need to pass parameters to the load function? How to do?

@David Sigley 2017-02-01 11:38:36

until (a = gets.chomp) =~ /(?:ex|qu)it/i send(a) end

@cwd 2015-08-08 13:09:25

Three Ways: send / call / eval - and their Benchmarks

Typical invocation (for reference):

s= "hi man"
s.length #=> 6

Using send

s.send(:length) #=> 6

Using call

method_object = s.method(:length) 
p method_object.call #=> 6

Using eval

eval "s.length" #=> 6

 

Benchmarks

require "benchmark" 
test = "hi man" 
m = test.method(:length) 
n = 100000 
Benchmark.bmbm {|x| 
  x.report("call") { n.times { m.call } } 
  x.report("send") { n.times { test.send(:length) } } 
  x.report("eval") { n.times { eval "test.length" } } 
} 

...as you can see, instantiating a method object is the fastest dynamic way in calling a method, also notice how slow using eval is.

#######################################
#####   The results
#######################################
#Rehearsal ----------------------------------------
#call   0.050000   0.020000   0.070000 (  0.077915)
#send   0.080000   0.000000   0.080000 (  0.086071)
#eval   0.360000   0.040000   0.400000 (  0.405647)
#------------------------------- total: 0.550000sec

#          user     system      total        real
#call   0.050000   0.020000   0.070000 (  0.072041)
#send   0.070000   0.000000   0.070000 (  0.077674)
#eval   0.370000   0.020000   0.390000 (  0.399442)

Credit goes to this blog post which elaborates a bit more on the three methods and also shows how to check if the methods exist.

@thesecretmaster 2015-11-20 22:14:42

I was just finding this, and I noticed something that wasn't covered. What would I do if I wanted to do Class.send("classVariable") = 5? That throws an error. Is there any way around that? The same thing is true for using Class.method("classVariable").call() = 5

@Aleem 2017-08-30 10:07:29

if you want to send some argument with send call use something like this ClassName.send("method_name", arg1, arg2)

@Joshua Pinter 2017-12-30 22:29:13

Shouldn't your benchmark for call include instantiating the method object (m.test.method(:length)) to accurately represent it's true time? When using call you're likely going to instantiate the method object every time.

@Joshua Pinter 2017-12-30 22:30:15

Blog post link is dead, btw.

@Geo 2009-09-10 20:18:56

Use this:

> a = "my_string"
> meth = a.method("size")
> meth.call() # call the size method
=> 9

Simple, right?

As for the global, I think the Ruby way would be to search it using the methods method.

@user1735921 2015-11-16 07:07:31

meth = a.method? isn't this call the function already? what if the method returns something?

@Joshua Pinter 2017-12-30 22:31:17

FYI for when the method doesn't exist: "my_string".method('blah') #=> NameError: undefined method blah' for class String'

@dlamblin 2009-09-10 20:16:03

Personally I would setup a hash to function references and then use the string as an index to the hash. You then call the function reference with it's parameters. This has the advantage of not allowing the wrong string to call something you don't want to call. The other way is to basically eval the string. Do not do this.

PS don't be lazy and actually type out your whole question, instead of linking to something.

@BuddyJoe 2009-09-10 20:37:59

Sorry. I'll copy some of the wording and translate to make it Ruby specific. +1

Related Questions

Sponsored Content

20 Answered Questions

[SOLVED] Calling shell commands from Ruby

  • 2008-08-05 12:56:52
  • CodingWithoutComments
  • 509932 View
  • 1027 Score
  • 20 Answer
  • Tags:   ruby shell interop

50 Answered Questions

[SOLVED] How to generate a random string in Ruby

10 Answered Questions

[SOLVED] How to convert a string to lower or upper case in Ruby

10 Answered Questions

[SOLVED] Can I invoke an instance method on a Ruby module without including it?

  • 2008-11-26 23:03:37
  • Orion Edwards
  • 121660 View
  • 171 Score
  • 10 Answer
  • Tags:   ruby module methods

9 Answered Questions

[SOLVED] How to check whether a string contains a substring in Ruby?

  • 2011-11-24 14:21:15
  • BSalunke
  • 699246 View
  • 693 Score
  • 9 Answer
  • Tags:   ruby string

5 Answered Questions

[SOLVED] Breaking up long strings on multiple lines in Ruby without stripping newlines

  • 2012-05-09 18:58:10
  • chug2k
  • 113286 View
  • 212 Score
  • 5 Answer
  • Tags:   ruby-on-rails ruby

9 Answered Questions

[SOLVED] Ruby: Calling class method from instance

  • 2010-03-27 01:48:01
  • Peter
  • 175247 View
  • 331 Score
  • 9 Answer
  • Tags:   ruby class-method

10 Answered Questions

[SOLVED] Why are exclamation marks used in Ruby methods?

1 Answered Questions

[SOLVED] Ruby: why does puts call to_ary?

36 Answered Questions

[SOLVED] What does Ruby have that Python doesn't, and vice versa?

  • 2009-07-11 12:24:26
  • Lennart Regebro
  • 125546 View
  • 264 Score
  • 36 Answer
  • Tags:   python ruby

Sponsored Content