Puoi farmi un esempio?Qual è la differenza tra Metodi e Attributi in Ruby?
risposta
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
.
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"
Penso che questa sia una risposta molto migliore rispetto alla risposta approvata ... –
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.
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.
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.
È sempre possibile accedere alla variabile utilizzando Object.instance_variable_get (: @ symbol), che elude la necessità di definire i metodi di accesso. –
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). –