What Does Send() Do in Ruby

What does send() do in Ruby?

send sends a message to an object instance and its ancestors in class hierarchy until some method reacts (because its name matches the first argument).

Practically speaking, those lines are equivalent:

1.send '+', 2
1.+(2)
1 + 2

Note that send bypasses visibility checks, so that you can call private methods, too (useful for unit testing).


If there is really no variable before send, that means that the global Object is used:

send :to_s    # "main"
send :class # Object

What is the send() method used for?

The Ruby implementation for the send method, which is used to send a method message to an object, works like this:

class Car

def start
puts "vroom"
end

private

def engine_temp
puts "Just Right"
end

end

@car = Car.new
@car.start # output: vroom
@car.send(:start) # output: vroom

That's the basics, an additional piece of important information is that send will allow you you send in messages to PRIVATE methods, not just public ones.

@car.engine_temp  # This doesn't work, it will raise an exception
@car.send(:engine_temp) # output: Just Right

As for what your specific send call will do, more than likely there is a def method_missing in the Performer class that is setup to catch that and perform some action.

send method in Ruby

First of all, things like [] (array index) and []= are just methods in Ruby. x is an Array, and arrays have a []= method, which accepts two arguments, an index and a value to set.

Using send lets you pass an arbitrary "message" (method call) to object, with arbitrary parameters.

You could call x.send :sort, for example, to send the "sort" message to the array. Sort doesn't need any parameters, though, so we don't have to pass anything extra to it.

x#[]=, on the other hand, accepts two arguments. Its method can be thought of to look like this:

def []=(index, value)
self.set_value_at_index(index, value)
end

So, we can just invoke it with send :[]=, 0, 2, which is just like calling x[0] = 2. Neat, huh?

Ruby `send` vs `call` method

To begin with, send and call are two very different methods.

In ruby, the concept of object orientation takes its roots from Smalltalk. Basically, when you call a method, you are sending that object a message. So, it makes sense that when you want to dynamically call a method on an object, the method you call is send. This method has existed in ruby since at least 1.8.7.

In ruby, we also have a concept of "blocks". Blocks are the do...end things attached to the end of method calls. Blocks can be traditionally yielded to; or, it is entirely possible to create an object out of a block (a Proc), and pass that around. In order to execute the block, you can call call on the block.

call has never been defined on Object, whereas send is defined on everything.

(note: for some reason, call doesn't seem to have documentation in the 2.3.0 documentation; however, it still exists and does the same thing from 2.2.0, so I linked that one instead.)

What is the point of using send instead of a normal method call?

It can come in handy if you don't know in advance the name of the method, when you're doing metaprogramming for example, you can have the name of the method in a variable and pass it to the send method.

It can also be used to call private methods, although this particular usage is not considered to be a good practice by most Ruby developers.

class Test
private
def my_private_method
puts "Yay"
end
end

t = Test.new

t.my_private_method # Error

t.send :my_private_method #Ok

You can use public_send though to only be able to call public methods.

Ruby send vs __send__

Some classes (for example the standard library's socket class) define their own send method which has nothing to do with Object#send. So if you want to work with objects of any class, you need to use __send__ to be on the safe side.

Now that leaves the question, why there is send and not just __send__. If there were only __send__ the name send could be used by other classes without any confusion. The reason for that is that send existed first and only later it was realized that the name send might also usefully be used in other contexts, so __send__ was added (that's the same thing that happened with id and object_id by the way).

Is there a send method in JavaScript the way there is in Ruby to help DRY this up?

I might be misunderstanding your question... but why don't you just save the config to a variable and use it:

var config = {
headerTag: "h3",
bodyTag: "section"
//other settings that make this steps method long
}

formWizard.steps(config);
var formWizard2 = $('form#myform').children('div.page-2');
formWizard2.send(config)

Difference between using send method and dot method

ticket.request sends the message request to the ticket object.

ticket.send(request) sends whatever is contained in the variable request to the ticket object. So if you had written request = :clone before this, that line would be equivalent to ticket.clone.

Understanding Ruby on Rails send(:include

You can't just do include because it's a private method, so you use send which circumvents ruby visibility control. With send you can call any method, even private ones (as in this case).

where is this method include defined and what does it does?

It's defined as Module#include and, when invoked with a module as a parameter, it appends all instance methods of that module to the receiver (which is, in your case, Issue class). It's a very-very common idiom in Ruby.



Related Topics



Leave a reply



Submit