Methods in Ruby: Objects or Not

Methods in Ruby: objects or not?

Methods are a fundamental part of
Ruby's syntax, but they are not values
that Ruby programs can operate on.
That is, Ruby's methods are not
objects
in the way that strings,
numbers, and arrays are. It is
possible, however, to obtain a Method
object that represents a given method,
and we can invoke methods indirectly
through Method objects.

From The Ruby Programming Language:

alt text

Ruby functions vs methods

lambdas in Ruby are objects of class Proc. Proc objects don't belong to any object. They are called without binding them to an object.

Methods are objects of either class Method or UnboundMethod, depending on whether they're bound or unbound. See the explanation here. Unbound methods can't be called until they're bound to an object.

lambda{|x| x}.class      # => Proc
lambda{|x| x}.call(123) # => 123

class Foo
def bar(baz)
baz
end
end

puts Foo.new.method(:bar).class # => Method
puts Foo.new.method(:bar).call(123) # => 123

puts Foo.instance_method(:bar).class # => UnboundMethod
puts Foo.instance_method(:bar).call(123) # => throws an exception

You can bind an UnboundMethod to an object and then call it. But you can't bind a Proc to an object at all. Proc objects can however capture local variables in the surrounding scope, becoming closures.

different way to create object specific methods in ruby

You have defined class block as class << obj1 for only obj1 object which is object specific.
So greet method is only defined for obj1 object and not for other objects of same class.

Better you inspect in following pattern

class Test
attr_accessor :name

def initialize(name)
self.name = name
end
end

obj1 = Test.new('test1')

class << obj1
def greet
puts self.inspect, self.object_id, self.name
puts 'Welcome'
end
end

obj1.greet
obj2 = Test.new
obj2.greet

In above, obj1 & obj2 both have different object ids.

1. What is the real world use of such kind of object specific methods?

It is good practice to know various pattern to define methods. This is useful when you want to define methods dynamically or when you load classes but want to define methods based on columns of model table present in database. Module#define_method is one of the best for such uses, cancancan is one of the gem who define helper methods dynamically in initializer.

2. What are other different ways to create object specific methods in Ruby?

  1. define_singleton_method
  2. class_eval

Are methods also objects like functions are?

It is quite easy to verify that the method is an object:

class Foo {
bar() {}
}

void main() {
print(Foo().bar is Object); // prints true
}

and linter shows a warning:

Unnecessary type check, the result is always true

How to list all methods for an object in Ruby?

The following will list the methods that the User class has that the base Object class does not have...

>> User.methods - Object.methods
=> ["field_types", "maximum", "create!", "active_connections", "to_dropdown",
"content_columns", "su_pw?", "default_timezone", "encode_quoted_value",
"reloadable?", "update", "reset_sequence_name", "default_timezone=",
"validate_find_options", "find_on_conditions_without_deprecation",
"validates_size_of", "execute_simple_calculation", "attr_protected",
"reflections", "table_name_prefix", ...

Note that methods is a method for Classes and for Class instances.

Here's the methods that my User class has that are not in the ActiveRecord base class:

>> User.methods - ActiveRecord::Base.methods
=> ["field_types", "su_pw?", "set_login_attr", "create_user_and_conf_user",
"original_table_name", "field_type", "authenticate", "set_default_order",
"id_name?", "id_name_column", "original_locking_column", "default_order",
"subclass_associations", ...
# I ran the statements in the console.

Note that the methods created as a result of the (many) has_many relationships defined in the User class are not in the results of the methods call.

Added Note that :has_many does not add methods directly. Instead, the ActiveRecord machinery uses the Ruby method_missing and responds_to techniques to handle method calls on the fly. As a result, the methods are not listed in the methods method result.

Is everything an object in ruby?

Depends on what you mean by "everything". Fixnums are, as the others have demonstrated. Classes also are, as instances of class Class. Methods, operators and blocks aren't, but can be wrapped by objects (Proc). Simple assignment is not, and can't. Statements like while also aren't and can't. Comments obviously also fall in the latter group.

Most things that actually matter, i.e. that you would wish to manipulate, are objects (or can be wrapped in objects).

Non-object-oriented aspects in ruby

puts() is a method in the IO class. See http://www.ruby-doc.org/core-2.1.3/IO.html#method-i-puts

IRB is a module, so it's an Object too. See http://ruby-doc.com/docs/ProgrammingRuby/html/irb.html

Examples of 'Things' that are not Objects in Ruby

The most obvious one that jumps into my head would be blocks. Blocks can be easily reified to a Proc object, either by using the &block parameter form in a parameter list or by using lambda, proc, Proc.new or (in Ruby 1.9) the "stabby lambda" syntax. But on its own, they aren't objects.

Another example are operators.



Related Topics



Leave a reply



Submit