BinaryWebPark

Ruby fundamentals: Method Inspection and Send

August 07, 2012

Ruby is what is considered an object-oriented programming language. This means calculations, the manipulation of data, and other operations are performed on “objects”. In programming terms, an object is an instance representation of something in the real world. For example, you could have a “car” object in Ruby that has properties like “wheels”, “color” and so forth. But one of the thing that stands out for me in Ruby is that…

Everything (almost) in Ruby is considered an object

I add the “almost” qualifier because there are some syntactical features of the language (e.g., keywords like if or end) that would not be considered objects. And an object has methods. And one exciting feature of Ruby is that it has a method to tell you what methods an object has

It’s called “methods”

If you’re ever struggling to remember what “that method” for a String object is called, at the command prompt you can type something like:

mystring=String.new("abc123")
mystring.methods.sort

And you will get back:

["%", "\*", "+", "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", "[]", "[]=", "**id**", "**send**", "all?", "any?", "between?", "bytes", "bytesize", "capitalize", "capitalize!", "casecmp", "center", "chars", "chomp", "chomp!", "chop", "chop!", "class", "clone", "collect", "concat", "count", "crypt", "cycle", "delete", "delete!", "detect", "display", "downcase", "downcase!", "drop", "drop_while", "dump", "dup", "each", "each_byte", "each_char", "each_cons", "each_line", "each_slice", "each_with_index", "empty?", "end_with?", "entries", "enum_cons", "enum_for", "enum_slice", "enum_with_index", "eql?", "equal?", "extend", "find", "find_all", "find_index", "first", "freeze", "frozen?", "grep", "group_by", "gsub", "gsub!", "hash", "hex", "id", "include?", "index", "inject", "insert", "inspect", "instance_eval", "instance_exec", "instance_of?", "instance_variable_defined?", "instance_variable_get", "instance_variable_set", "instance_variables", "intern", "is_a?", "kind_of?", "length", "lines", "ljust", "lstrip", "lstrip!", "map", "match", "max", "max_by", "member?", "method", "methods", "min", "min_by", "minmax", "minmax_by", "next", "next!", "nil?", "none?", "object_id", "oct", "one?", "partition", "private_methods", "protected_methods", "public_methods", "reduce", "reject", "replace", "respond_to?", "reverse", "reverse!", "reverse_each", "rindex", "rjust", "rpartition", "rstrip", "rstrip!", "scan", "select", "send", "singleton_methods", "size", "slice", "slice!", "sort", "sort_by", "split", "squeeze", "squeeze!", "start_with?", "strip", "strip!", "sub", "sub!", "succ", "succ!", "sum", "swapcase", "swapcase!", "taint", "tainted?", "take", "take_while", "tap", "to_a", "to_enum", "to_f", "to_i", "to_s", "to_str", "to_sym", "tr", "tr!", "tr_s", "tr_s!", "type", "unpack", "untaint", "upcase", "upcase!", "upto", "zip"]

You can see calling “sort” on mystring.methods gives you a sorted list so it’s easier to sift through.

Another interesting feature of Ruby is the send method

In Ruby, “mystring.length” means call method “length” on object “mystring.” In Ruby parlance, mystring is a “receiver” to which you send the method call “length”. This assumes that “mystring” will respond to that method (i.e., that is one of the methods defined for a String object such as mystring).

If you’re coming from an object-oriented language like C++, “mystring.length” does not mean that “length” is an instance variable of “mystring” (like it would be in C++ if mystring was a C++ struct). It also does not mean that “mystring” is some type of data structure with “length” as a member.  “mystring.length” means that you are calling the length method on the object mystring. “mystring” is a receiver to which you send the method “length”, assuming “mystring” responds to the “length” method.

Now, Ruby defines a method for all objects that literally makes this apparent, and it’s called the send method.

Instead of mystring.length, you can call:

mystring.send(:length)

One interesting application of having the send method available for all your objects is that it can help you DRY up your code (talked about in an upcoming post).