Quickly Filtering Ruby Methods

Ruby on Rails

Sometimes, when working with IRB or the Rails console, you might need a list of methods on a particular class or object. You don’t necessarily need to consult the doc because it is one of those situations where you would know the method if you saw it. So what do you do? Well, one trick is to use the select method (passed via a block) on a collection of methods. You can always start by asking the class for its methods by typing the following:

Hash.methods

Which yields:

["require_dependency", "decode_b", "write_inheritable_hash", "model_name", "breakpoint", "require", "delegate", "taguri", "const_missing", "new", "class_inheritable_hash", "suppress", "methods", "andand", "method", "allocate", "attr_internal_reader", "protected_instance_methods", "deprecate", "taguri=", "subclasses", "cattr_accessor", "include?", "daemonize", "taint", "present?", "class_eval", "alias_method_chain", "instance_variable_defined?", "yaml_tag_class_name", "name", "find_hidden_method", "reset_inheritable_attributes", "metaclass", "autoload", "to_yaml_style", "class_variables", "parent", "inheritable_attributes", "__id__", "singleton_methods", "synchronize", "dclone", "private_instance_methods", "object_id", "subclasses_of", "respond_to?", "nil?", "ancestors", "yaml_tag_read_class", "parent_name", "tap", "__send__", "require_library_or_gem", "protected_methods", "require_or_load", "me", "tainted?", "attr_internal_writer", "remove_class", "class_inheritable_reader", "untaint", "instance_of?", "autoload?", "b64encode", "included_in_classes", "equal?", "method_defined?", "with_options", "const_missing_without_dependencies", "display", "class_variable_defined?", "private_methods", "hash", "instance_method", "send", "constants", "deprecation_horizon", "instance_values", "`", "attr_internal_accessor", "yaml_tag_subclasses?", "class_inheritable_writer", "kind_of?", "enable_warnings", "freeze", "eql?", "public_method_defined?", "to_json", "id", "returning", "parents", "write_inheritable_attribute", "dont", "acts_like?", "require_association", "public_methods", "instance_eval", "superclass_delegating_reader", "instance_variable_names", "attr_internal", "const_get", "to_enum", "class_inheritable_array_writer", "is_a?", "silence_stderr", "private_method_defined?", "cattr_reader", "type", "const_missing_with_dependencies", "local_constants", "superclass", "write_inheritable_array", "instance_variables", "frozen?", "blank?", "attr_internal_naming_format", "const_set", "copy_instance_variables_from", "enum_for", "class_inheritable_hash_writer", "silence_stream", "to_a", "to_param", "mattr_reader", "protected_method_defined?", "attr_internal_naming_format=", "extended_by", "silence_warnings", "class", "public_class_method", "encode64", "from_xml", "instance_variable_get", "<=>", "to_yaml", "load_with_new_constant_marking", "==", "superclass_delegating_writer", "method_added", "class_inheritable_accessor", "===", "duplicable?", "extend", "to_s", "to_query", "alias_attribute", "instance_methods", ">=", "remove_subclasses", "extend_with_included_modules_from", "mattr_writer", "<=", "cattr_writer", "local_constant_names", "clone", "private_class_method", "decode64", "read_inheritable_attribute", "const_defined?", "yaml_as", "included_modules", "debugger", "=~", "instance_variable_set", "<", "superclass_delegating_accessor", "deprecated_method_warning", "attr_accessor_with_default", ">", "class_inheritable_array", "inspect", "[]“, “remove_subclasses_of”, “instance_exec”, “try”, “mattr_accessor”, “public_instance_methods”, “as_load_path”, “to_yaml_properties”, “unloadable”, “dup”, “module_eval”]

OK, yeah, that’s a bit overkill. How about we narrow it down to the types of methods (using the select method with a regular expression):

Hash.methods {|m| m.select =~ /methods/}

Which yields:

["methods", "protected_instance_methods", "singleton_methods", "private_instance_methods", "protected_methods", "private_methods", "public_methods", "instance_methods", "public_instance_methods"]

Ah, much better. …but I’m not quite there yet. Lets say I know it’s an instance method and it is a type of “to” method. I could then type the following:

Hash.instance_methods {|m| m.select =~ /to_/}

Which yields:

["to_yaml_style", "to_hash", "to_set", "to_xml", "to_json", "to_enum", "to_options", "to_a", "to_param", "to_yaml", "to_options!", "to_s", "to_query", "to_yaml_properties"]

OK, now I remember, it was the “to_yaml” method that I was looking for!

This, of course, is a contrived example. However, if you know what type of method you are looking for and part of its name, then this is a quick and effective way of getting back a subset of methods from which you can gauge what it is that you’re looking for.

Where I tend use this most (as of late) is with Rails models that accept nested attributes (i.e. accepts_nested_attributes_for). For example:

Recipe.instance_methods {|m| m.select =~ /attributes/}

["update_attributes!", "comments_attributes=", "reject_new_nested_attributes_procs", "attributes", "attributes=", "time_zone_aware_attributes", "respond_to_without_attributes?", "update_attributes", "skip_time_zone_conversion_for_attributes", "user_recipe_attributes=", "ingredient_groups_attributes=", "attributes_before_type_cast", "instructions_attributes=", "sources_attributes="]

So there you have it, in case it is of help.

Tags: ,

Tuesday, June 16th, 2009 Software

No comments yet.

Leave a comment

You must be logged in to post a comment.