2009-07-28 31 views

risposta

28

Gli attributi sono proprietà specifiche di un oggetto. I metodi sono funzionalità di un oggetto.

In Ruby tutte le variabili di istanza (attributi) sono private per impostazione predefinita. Significa che non hai accesso ad essi al di fuori dell'ambito dell'istanza stessa. L'unico modo per accedere all'attributo è utilizzare un metodo di accesso.

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" 

Poiché questo è un comportamento molto commmon, rubino fornisce un metodo conveniente definire metodi accessori: attr_accessor, attr_writer e attr_reader.

+1

È sempre possibile accedere alla variabile utilizzando Object.instance_variable_get (: @ symbol), che elude la necessità di definire i metodi di accesso. –

+6

Questa non è davvero una buona pratica. ;) istanza_variabile_get dovrebbe essere riservato per la metaprogrammazione. È come definire un metodo come privato quindi accedervi con send (: method). –

38

Gli attributi sono solo una scorciatoia. Se si utilizza attr_accessor per creare un attributo, Ruby dichiara semplicemente una variabile di istanza e crea i metodi getter e setter per te.

Dal momento che si chiede per un esempio:

class Thing 
    attr_accessor :my_property 

    attr_reader :my_readable_property 

    attr_writer :my_writable_property 

    def do_stuff 
     # does stuff 
    end 
end 

Ecco come devi usare la classe:

# 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" 
+3

Penso che questa sia una risposta molto migliore rispetto alla risposta approvata ... –

4

Gli attributi sono, in senso stretto, le variabili di istanza di un'istanza di classe. In termini più generali, gli attributi sono generalmente dichiarati usando i metodi tipo attr_X, mentre i metodi sono semplicemente dichiarati così come sono.

Un semplice esempio potrebbe essere:

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 

La distinzione tra questi due è alquanto arbitraria rubino poiché nessun accesso diretto ad essi è espressamente previsto. Ciò contrasta fortemente con altri linguaggi come C, o C++ e Java dove l'accesso alle proprietà di un oggetto e ai metodi di chiamata avviene attraverso due meccanismi diversi. In particolare, Java ha metodi di accesso/mutatore che sono espressi come tali, mentre in Ruby sono impliciti per nome.

È spesso il caso, come nell'esempio, in cui la differenza tra un "attributo accessore" e un metodo di utilità che fornisce dati in base al valore di un attributo, ad esempio truncated_name, è minore.

1
class MyClass 
    attr_accessor :point 

    def circle 
    return @circle 
    end 

    def circle=(c) 
    @circle = c 
    end 
end 

Un attributo è una proprietà dell'oggetto. In questo caso, utilizzo il metodo della classe attr_accessor per definire la proprietà: point insieme a metodi getter e setter impliciti per il punto.

obj = MyClass.new 
obj.point = 3 
puts obj.point 
> 3 

Il metodo 'circle' è un getter esplicitamente definito per la variabile di istanza @circle. 'circle =' è un setter esplicitamente definito per la variabile di istanza @circle.

0

Ho sentito che la parola "attributo" si riferisce, nei cerchi specifici di Ruby, a qualsiasi metodo che non accetta argomenti.

class Batman 

    def favorite_ice_cream 
    [ 
     'neopolitan', 
     'chunky monkey', 
     'chocolate', 
     'chocolate chip cookie dough', 
     'whiskey' 
    ].shuffle[0]   
    end 

end 

In quanto sopra, my_newest_batman.favorite_ice_cream sarebbe un attributo.

Problemi correlati