My Methods

Posted by Matt Williams

One of the really nice things about Ruby is its ability to change the behaviour of its classes. So it is easy to add new behaviours, as needed to a class.

The Object class has a method, methods, which allows you to see the objects associated with a particular object.

1
2
3

>> "methods".methods
=> ["chop!", "concat", "upcase!", "collect", "pretty_print_cycle", "sort", "member?", "methods", "chop", "replace", "gem", "include?", "each_with_index", "taint", "instance_variable_defined?", "empty?", "crypt", "chomp!", "downcase!", "map", "match", "slice!", "pretty_print", "__id__", "sort_by", "singleton_methods", "chomp", "tr!", "my_methods", "zip", "respond_to?", "to_str", "dclone", "po", "nil?", "intern", "strip!", "capitalize!", "inject", "succ", "__send__", "__clone__", "protected_methods", "grep", "tainted?", "strip", "tr_s!", "each", "dump", "untaint", "instance_of?", "pretty_print_instance_variables", "scan", "lstrip!", "equal?", "swapcase!", "partition", "hex", "private_methods", "hash", "find", "lstrip", "delete!", "send", "upcase", "require", "kind_of?", "succ!", "poc", "freeze", "rstrip!", "eql?", "pretty_inspect", "ljust", "method", "next", "tr", "id", "oct", "detect", "public_methods", "casecmp", "squeeze!", "instance_eval", "unpack", "rstrip", "%", "downcase", "is_a?", "each_line", "all?", "rjust", "object_id", "type", "*", "tr_s", "split", "+", "find_all", "instance_variables", "insert", "frozen?", "capitalize", "any?", "ri", "to_a", "next!", "pretty_print_inspect", "each_byte", "center", "min", "upto", "class", "delete", "to_sym", "reverse", "build_hash", "sub!", "<=>", "instance_variable_get", "length", "select", "==", "between?", "===", "to_i", "swapcase", "to_s", "extend", "display", "sum", "sub", ">=", "max", "<=", "index", "squeeze", "clone", "gsub!", "=~", "instance_variable_set", "size", "<", "what?", "reject", ">", "to_f", "entries", "slice", "inspect", "[]", "gsub", "rindex", "reverse!", "[]=", "count", "dup", "<<"]
However, the Object class has methods:
1
2
3

>> Object.new.methods
=> ["inspect", "clone", "pretty_print_cycle", "method", "__clone__", "public_methods", "pretty_print_inspect", "instance_variable_defined?", "equal?", "freeze", "poc", "methods", "respond_to?", "pretty_inspect", "pretty_print", "dup", "instance_variables", "__id__", "eql?", "object_id", "require", "what?", "id", "singleton_methods", "send", "pretty_print_instance_variables", "taint", "frozen?", "instance_variable_get", "__send__", "instance_of?", "to_a", "gem", "ri", "type", "protected_methods", "instance_eval", "==", "display", "===", "instance_variable_set", "po", "my_methods", "kind_of?", "extend", "to_s", "class", "hash", "dclone", "private_methods", "=~", "tainted?", "untaint", "nil?", "is_a?"]
Trying to figure out which methods are associated with an object and which it has inherited from Object can be interesting. But the methods method returns an array, and in Ruby, when you subtract one array from another, you subtract the intersection between the first and second array:
1
2
3

>> "methods".methods - Object.new.methods
=> ["chop!", "concat", "upcase!", "collect", "sort", "member?", "chop", "replace", "include?", "each_with_index", "empty?", "crypt", "chomp!", "downcase!", "map", "match", "slice!", "sort_by", "chomp", "tr!", "zip", "to_str", "intern", "strip!", "capitalize!", "inject", "succ", "grep", "strip", "tr_s!", "each", "dump", "scan", "lstrip!", "swapcase!", "partition", "hex", "find", "lstrip", "delete!", "upcase", "succ!", "rstrip!", "ljust", "next", "tr", "oct", "detect", "casecmp", "squeeze!", "unpack", "rstrip", "%", "downcase", "each_line", "all?", "rjust", "*", "tr_s", "split", "+", "find_all", "insert", "capitalize", "any?", "next!", "each_byte", "center", "min", "upto", "delete", "to_sym", "reverse", "build_hash", "sub!", "<=>", "length", "select", "between?", "to_i", "swapcase", "sum", "sub", ">=", "max", "<=", "index", "squeeze", "gsub!", "size", "<", "reject", ">", "to_f", "entries", "slice", "[]", "gsub", "rindex", "reverse!", "[]=", "count", "<<"]
But typing that on a regular basis gets old. Herein comes the niceness of being able to add to classes as needed. By adding a method to Object we can ensure that our method is available for any object created:
1
2
3
4
5
6

class Object
  def my_methods
    self.methods - Object.methods
  end
end
Let's see it now:
1
2
3

>> "methods".my_methods
=> ["chop!", "concat", "upcase!", "collect", "sort", "member?", "chop", "replace", "each_with_index", "empty?", "crypt", "chomp!", "downcase!", "map", "match", "slice!", "sort_by", "chomp", "tr!", "zip", "to_str", "intern", "strip!", "capitalize!", "inject", "succ", "grep", "strip", "tr_s!", "each", "dump", "scan", "lstrip!", "swapcase!", "partition", "hex", "find", "lstrip", "delete!", "upcase", "succ!", "rstrip!", "ljust", "next", "tr", "oct", "detect", "casecmp", "squeeze!", "unpack", "rstrip", "%", "downcase", "each_line", "all?", "rjust", "*", "tr_s", "split", "+", "find_all", "insert", "capitalize", "any?", "next!", "each_byte", "center", "min", "upto", "delete", "to_sym", "reverse", "build_hash", "sub!", "length", "select", "between?", "to_i", "swapcase", "sum", "sub", "max", "index", "squeeze", "gsub!", "size", "reject", "to_f", "entries", "slice", "[]", "gsub", "rindex", "reverse!", "[]=", "count", "<<"]
We still don't want to have to type this all the time. Also, it only works on objects which are created after we modify Object. So, we can add our method definition to the .irbrc, where it will be picked up any time we have an interactive ruby session. Update: Joe O'Brien of Edgecase suggested adding a sort to the self.methods to make the output sorted.
Comments

Leave a response