views:

911

answers:

5

Can you give me an example?

+3  A: 

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"
Rafe
+6  A: 

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, 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.

Simone Carletti
You can always access variable using Object.instance_variable_get(:@symbol), which circumvents the need to define accessors.
BigCanOfTuna
This is not really a good practice. ;) instance_variable_get should be reserved for metaprogramming stuff. It's like defining a method as private then accessing it with send(:method).
Simone Carletti
+3  A: 

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.

tadman
+1  A: 
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 difined setter for the @circle instance variable.

BigCanOfTuna
A: 

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.

Luke Griffiths