class Artist
@@song_count = []
attr_accessor :name, :songs
def initialize(name)
@name = name
@songs = []
end
def add_song(song)
@songs << song
end
def print_songs
songs.each {|song| puts song.name}
end
end
所以在这个例子中,它使用了所有两种类型,@ song和song。
我很难理解为什么使用这些,而不是使用@songs来处理所有事情。
然后在这个例子中,
def add_song(song)
self.songs << song
song.artist = self
@@song_count +=1
end
为什么使用self.songs而不是@songs?
好的,所以我忘了再说一件事。在上面的第一个代码片段中,对于方法print_songs,为什么我能够使用songs.each而不是@ songs.each?我原本以为它会产生错误的未定义歌曲。
答案 0 :(得分:2)
为什么要使用self.songs而不是@songs
使用该方法更灵活。您可以从了解自己获取/存储数据的确切方式中抽象自己。您对实现细节的依赖程度越低,以后您就越容易更改代码。
一个小例子,考虑songs
def songs
@songs ||= []
@songs
end
在调用此方法之前, @songs
可能已经或未被赋值。但它并不关心。它确保@songs
具有合理的默认值。这个概念被称为&#34;懒惰初始化&#34;如果直接使用实例变量,它会非常繁琐且容易出错。
因此,如果有疑问,请始终使用方法。
答案 1 :(得分:1)
foo
和@foo
实例变量在实例方法中定义,其名称以@开头。它们的值只能在设置它的特定对象中访问。换句话说,当我们修改实例变量的值时,更改仅适用于该特定实例。与仅在定义它们的方法中可用的局部变量不同,实例变量可由对象内的所有方法访问(类的实例方法)。实例变量是Ruby类中最常用的变量类型。
class Car
attr_reader :color
def set_color(color_receiverd_as_argument)
@color = color_receiverd_as_argument
end
end
car1 = Car.new
car1.color # Output: => nil
car1.set_color "black"
car1.color # Output: => "black"
car2 = Car.new
car2.set_color "silver"
car2.color # Output: => "silver"
在上面的示例中,请注意:
类中的局部变量就像Ruby中的任何其他局部变量一样。它只能在其创建的确切范围内访问。如果在方法中定义,则仅在该方法内可用。
class Car
def initialize
wheels = 4
end
def print_wheels
print wheels
end
end
c = Car.new
c.print_wheels # Output: NameError: undefined local variable or method `wheels'…
self关键字始终可用,它指向当前对象。在Ruby中,所有方法调用都包含发送给接收方的消息。换句话说,在对象上调用所有方法。调用该方法的对象是接收者,方法是消息。如果我们打电话给&#34; foo&#34; .upcase,&#34; foo&#34; object是接收者,upcase是消息。如果我们在调用方法时没有指定对象(接收者),则会在自身对象上隐式调用它。
在类中但在任何实例方法之外使用时,self指的是类本身。
class Foo
@@self_at_class_level = self
def initialize
puts "self at class level is #{@@self_at_class_level}"
end
end
f = Foo.new # Output: self at class level is Foo
在实例方法中,self关键字引用该特定实例。换句话说,它指的是调用它的对象。
class Meditation
def initialize
puts "self within an instance method is #{self}"
end
end
zazen = Meditation.new # Output: self within an instance method is #<Meditation:0x00000000ab2b38>
请注意#<Meditation:0x00000000ab2b38>
是zazen对象的字符串表示形式,它是Meditation类的一个实例。