2009-07-28 15 views

Antwort

28

Attribute sind bestimmte Eigenschaften eines Objekts. Methoden sind Fähigkeiten eines Objekts.

In Ruby sind alle Instanzvariablen (Attribute) standardmäßig privat. Dies bedeutet, dass Sie außerhalb des Anwendungsbereichs der Instanz keinen Zugriff darauf haben. Die einzige Möglichkeit, auf das Attribut zuzugreifen, ist die Verwendung einer Zugriffsmethode.

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" 

Da dies ein wirklich commmon Verhalten ist, bietet Rubin eine bequeme Methode Accessormethoden zu definieren: attr_accessor, attr_writer und attr_reader.

+1

Sie können immer mit Object.instance_variable_get (: @ -Symbol) zugreifen Variable, die die Notwendigkeit, Accessoren zu definieren umgeht. –

+6

Dies ist nicht wirklich eine gute Übung. ;) instance_variable_get sollte für Metaprogrammierungskram reserviert sein. Es ist, als würde man eine Methode als privat definieren und dann mit send (: method) darauf zugreifen. –

38

Attribute sind nur eine Abkürzung. Wenn Sie attr_accessor verwenden, um ein Attribut zu erstellen, deklariert Ruby nur eine Instanzvariable und erstellt Getter- und Setter-Methoden für Sie.

Da Sie für ein Beispiel gefragt:

class Thing 
    attr_accessor :my_property 

    attr_reader :my_readable_property 

    attr_writer :my_writable_property 

    def do_stuff 
     # does stuff 
    end 
end 

Hier ist, wie Sie die Klasse verwenden würde:

# 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

Ich denke, das ist eine viel bessere Antwort als die genehmigte Antwort ... –

4

Attribute sind streng genommen die Instanzvariablen einer Klasseninstanz. Allgemein gesagt werden Attribute normalerweise mit den Methoden vom Typ attr_X deklariert, während Methoden einfach so deklariert werden, wie sie sind.

Ein einfaches Beispiel könnte sein:

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 

Die Unterscheidung zwischen diesen beiden in Ruby etwas willkürlich ist, da kein direkter Zugriff auf sie speziell vorgesehen ist. Dies steht in starkem Kontrast zu anderen Sprachen wie C oder C++ und Java, wo der Zugriff auf Objekteigenschaften und Aufrufmethoden über zwei verschiedene Mechanismen erfolgt. Java verfügt insbesondere über Accessor/Mutator-Methoden, die als solche gekennzeichnet sind, während sie in Ruby mit dem Namen impliziert sind.

Wie im Beispiel ist der Unterschied zwischen einem "attribute accessor" und einer Hilfsmethode, die Daten basierend auf dem Wert eines Attributs wie trunked_name bereitstellt, häufig gering.

1
class MyClass 
    attr_accessor :point 

    def circle 
    return @circle 
    end 

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

Ein Attribut ist eine Eigenschaft des Objekts. In diesem Fall verwende ich die Attr_accessor-Klassenmethode, um die Eigenschaft: point zusammen mit einer impliziten Getter- und Setter-Methode für den Punkt zu definieren.

Die Methode 'circle' ist ein explizit definierter Getter für die @circle-Instanzvariable. 'circle =' ist ein explizit definierter Setter für die @circle-Instanzvariable.

0

Ich habe gehört, das Wort "Attribut" verweisen in Ruby-spezifischen Kreisen auf jede Methode, die keine Argumente akzeptiert.

class Batman 

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

end 

Im obigen my_newest_batman.favorite_ice_cream würde ein Attribut sein.

Verwandte Themen