Can you give me an example?
I have heard the word "attribute" refer, in Ruby-specific circles, to any method which does not take arguments.
class Batman
def favorite_ice_cream
[
'neopolitan',
'chunky monkey',
'chocolate',
'chocolate chip cookie dough',
'whiskey'
].shuffle[0]
end
end
In the above, my_newest_batman.favorite_ice_cream would be an attribute.
Attributes are just a shortcut. If you use attr_accessor
to create an attribute, Ruby just declares an instance variable and creates getter and setter methods for you.
Since you asked for an example:
class Thing
attr_accessor :my_property
attr_reader :my_readable_property
attr_writer :my_writable_property
def do_stuff
# does stuff
end
end
Here's how you'd use the class:
# Instantiate
thing = Thing.new
# Call the method do_stuff
thing.do_stuff
# You can read or write my_property
thing.my_property = "Whatever"
puts thing.my_property
# We only have a readable accessor for my_readable_property
puts thing.my_readable_property
# And my_writable_propety has only the writable accessor
thing.my_writable_property = "Whatever"
Attributes are, strictly speaking, the instance variables of a class instance. In more general terms, attributes are usually declared using the attr_X type methods, while methods are simply declared as is.
A simple example might be:
attr_accessor :name
attr_reader :access_level
# Method
def truncate_name!
@name = truncated_name
end
# Accessor-like method
def truncated_name
@name and @name[0,14]
end
# Mutator-like method
def access_level=(value)
@access_level = value && value.to_sym
end
The distinction between these two is somewhat arbitrary in Ruby since no direct access to them is specifically provided. This contrasts quite strongly with other languages such as C, or C++ and Java where access of an objects properties and calling methods is done through two different mechanisms. Java in particular has accessor/mutator methods that are spelled out as such, whereas in Ruby these are implied by name.
It is often the case, as in the example, where the difference between an "attribute accessor" and a utility method that provides data based on an attribute's value, such as truncated_name, is minor.
class MyClass
attr_accessor :point
def circle
return @circle
end
def circle=(c)
@circle = c
end
end
An attribute is a property of the object. In this case, I use the attr_accessor class method to define the :point property along with an implicit getter and setter methods for point.
obj = MyClass.new
obj.point = 3
puts obj.point
> 3
The method 'circle' is an explicitly defined getter for the @circle instance variable. 'circle=' is an explicitly defined setter for the @circle instance variable.
Attributes are specific properties of an object. Methods are capabilities of an object.
In Ruby all instance variables (attributes) are private by default. It means you don't have access to them outside the scope of the instance itself. The only way to access the attribute is using an accessor method.
class Foo
def initialize(color)
@color = color
end
end
class Bar
def initialize(color)
@color = color
end
def color
@color
end
end
class Baz
def initialize(color)
@color = color
end
def color
@color
end
def color=(value)
@color = value
end
end
f = Foo.new("red")
f.color # NoMethodError: undefined method ‘color’
b = Bar.new("red")
b.color # => "red"
b.color = "yellow" # NoMethodError: undefined method `color='
z = Baz.new("red")
z.color # => "red"
z.color = "yellow"
z.color # => "yellow"
Because this is a really commmon behavior, Ruby provides some convenient method to define accessor methods: attr_accessor
, attr_writer
and attr_reader
.