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:
Ruby functions vs methods
lambda
s 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?
- define_singleton_method
- 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". Fixnum
s 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
Does Ruby Have Real Multithreading
Ruby Block and Unparenthesized Arguments
How to Get a Random Number in Ruby
How to Run Rake Tasks from Within Rake Tasks
Eventsource/Server-Sent Events Through Nginx
Using Sinatra For Larger Projects Via Multiple Files
Submit Post Data from Controller to Another Website in Rails
How to Break Out from a Ruby Block
Why Are We Installing Ruby 1.9.2/1.9.3 Gems into a 1.9.1 Folder
What Are the Restrictions For Method Names in Ruby
Ruby Objects and Json Serialization (Without Rails)
Where Is Ruby'S String Literal Juxtaposition Feature Officially Documented
Valid Email Address Regular Expression
Backslashes in Single Quoted Strings Vs. Double Quoted Strings