Ruby — are you ‘calling a method’ or ‘sending a message’?

Rob Faldo
3 min readMar 29, 2019

--

I’m a ruby developer and something that has confused me in the past has been the phrase ‘calling the method on X’ or ‘sending the message to X” where X is an object. It almost seemed like people were using the two phrases interchangeably when describing a method call on an object.

So which is right?

The answer, perhaps unsurprisingly, is both! Let’s look at why.

Let’s think about an object in Ruby for a moment. Say you have an instance of the String class and you assign it to the variable example_object

example_object = "This is a string"

Okay, so our object has a bunch of methods available on it, in fact as an instance of the String class it has all of the instance methods that are included by default.

Sending the messages

I can send any message I like to our object with the . notation. I can send the message made_up_message_that_wont_work to it as such:example_object.made_up_message_that_wont_work . Sending a message doesn’t mean that it will work, as it won’t in this case, but the point is that I can send any message I like, and when using dot notation it’s represented as the right hand side of the dot.

Calling the method

First of all, let’s check what methods we can call on our example_object . We can do that by sending the message methods to the object which will then call the correspondingly named method (the methods method).

>> example_object.methods
=> [:include?, :%, :*, :+, :to_c, :unicode_normalize, :unicode_normalize!, :unicode_normalized?, :count, :partition, :unpack, :unpack1, :sum, :next, :casecmp, :casecmp?, :insert, :bytesize, :match, :match?, :+@, :-@, :upto, :index, :<=>, :replace, :succ!, :next!, :getbyte, :==, :===, :byteslice, :=~, :chr, :[], :[]=, :clear, :scrub, :scrub!, :rindex, :downcase, :upcase, :empty?, :eql?, :setbyte, :upcase!, :capitalize, :swapcase, :dump, :downcase!, :capitalize!, :swapcase!, :hex, :oct, :split, :codepoints, :bytes, :chars, :concat, :lines, :reverse!, :<<, :freeze, :inspect, :ord, :start_with?, :prepend, :crypt, :reverse, :rjust, :intern, :scan, :ljust, :chop, :length, :size, :gsub, :succ, :chomp, :gsub!, :sub, :end_with?, :sub!, :lstrip!, :rstrip, :delete, :rstrip!, :chop!, :to_str, :to_sym, :center, :tr!, :tr, :tr_s, :to_s, :to_i, :lstrip, :tr_s!, :delete!, :squeeze!, :each_line, :chomp!, :strip!, :strip, :slice, :slice!, :rpartition, :each_byte, :to_f, :each_codepoint, :valid_encoding?, :ascii_only?, :encoding, :force_encoding, :each_char, :squeeze, :encode, :encode!, :hash, :b, :to_r, :<, :>, :<=, :>=, :between?, :clamp, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :public_send, :public_method, :singleton_method, :instance_variable_defined?, :define_singleton_method, :method, :instance_variable_set, :extend, :to_enum, :enum_for, :!~, :respond_to?, :object_id, :send, :display, :nil?, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variable_get, :instance_variables, :!, :!=, :__send__, :equal?, :instance_eval, :instance_exec, :__id__]

Side note, the methods method is actually a method on the Object class, that our example_object has because it is an instance of the String class, and the String class inherits from the Object class. You can see it in the above list as one of the methods available in our object.

This means our object can receive any of the messages listed above, and when it does receive them it will execute the correspondingly named method, if one exists.

Conclusion

You can send any message to any object using the dot notation (but doesn’t mean that it will work).

When you send a message to an object, and that object has the corresponding method as a public interface, then that message will call the method on the object.

--

--

Rob Faldo
Rob Faldo

Written by Rob Faldo

Ruby Engineer @ Simply Business

Responses (1)