我正试图在Ruby中理解自我。
在下面粘贴的代码中,如果我使用
创建一个新的Animal实例 fox = Animal.new.name("Fox").color("red").natural_habitat("forest").specie("mammal")
然后致电
fox.to_s
如果我不在每种方法中返回自我,它什么都不做。
为什么我在每种方法中都需要自我?创建新动物后,该变量是否已保存?
class Animal
def name(name)
@name = name
self
end
def specie(specie)
@specie = specie
self
end
def color(color)
@color = color
self
end
def natural_habitat(natural_habitat)
@natural_habitat = natural_habitat
self
end
def to_s
"Name: #{@name}, Specie: #{@specie}, Color: #{@color}, Natural Habitat: #{@natural_habitat}"
end
end
答案 0 :(得分:3)
这种模式在Ruby中很少使用,它在Java和JavaScript等语言中更为常见,它在jQuery中显得十分猖獗。部分原因在于您在此处描述的详细程度,其次是因为Ruby以attr_accessor
或attr_writer
的形式提供了方便的mutator生成器。
这些存取器/增变器双重用途方法的一个问题是模糊性。您的实施不完整,您无法从中读取。你需要的是:
def color(*color)
case (color.length)
when 1
@color = color
self
when 0
@color
else
raise ArgumentError, "wrong number of arguments (%d for 0)" % color.length
end
end
实现可以通过两种方式使用的东西的大量代码:
animal.color('red')
animal_color = animal.color
如果你想使用它们,你需要编写自己的元编程方法来生成它们,尽管我一开始就非常不鼓励沿着这条路走下去。使用attr_accessor
方法和选项Hash。
这里是等效的Ruby模式:
# Up-front assignment via Hash
animal = Animal.new(
name: 'Fox',
color: 'red',
natural_habitat: 'forest',
specie: 'mammal'
)
# Assignment after the fact
animal.color = 'white'
答案 1 :(得分:1)
在您的示例中,使用self
作为返回值很方便。方法返回实例本身,以便您可以调用:
fox = Animal.new
fox.name("Fox").color("red").natural_habitat("forest").specie("mammal")
fox.name("Fox")
的值是实例本身,这就是您可以在其上调用.color("red")
的原因。
答案 2 :(得分:1)
如果#name方法在没有调用self的情况下实现,就像这样:
Animal.new.name.specie
此方法在调用时将返回一个字符串。
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let collectionViewWidth: CGFloat = collectionView.frame.size.width
let cellSize: CGFloat = collectionViewWidth / 2.0
return CGSizeMake(cellSize, cellSize);
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0.0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0.0
}
这意味着
{{1}}
会在字符串对象上调用#specie方法(可能会引发NotImplemented错误),而不是实现该方法的Animal类的对象。