我对此很困惑.. 像这样
class Box
attr_accessor :item ,:item2
def initialize(item2)
@item = []
@item2 = item2
end
def add(product)
item << product
end
def empty?
item.empty?
end
def increment(n=1)
item2 +=1
end
end
cart =Box.new(123)
cart.add(1)
puts cart.empty? #false
puts cart.item #1
在&#39;添加&#39;并且空了?&#39;方法 我使用本地变量&#39; item&#39;对? 为什么我可以从@items获得价值?
我试试这个
cart.item2 = 345
puts cart.item2 #345
puts cart.increment #'increment': undefined method `+' for nil:NilClass (NoMethodError)
现在我无法获得价值?
请修好我的脑子
答案 0 :(得分:4)
首先,阅读this answer,这是StackOverflow历史记录中最受欢迎的Ruby帖子。它有助于您了解attr_accessor
及其堂兄attr_reader
和attr_writer
。
除此之外,您的代码还有很多问题。
首先,不应将具有单数变量名称的数组命名为item
。使用复数items
来明确其目的。
其次,名称item2
并不好。对于您的属性,请使用像counter
这样的描述性内容,对于作为参数传递的变量来初始化它,让我们使用像initial_count
这样的描述性内容。
第三,你的increment
方法接受一个可选参数但忽略它。如果有人调用box.increment(2)
并且属性仅增加1,那会不会令人惊讶?此方法的目的是使用counter += n
而不是counter += 1
。
第四,要在班级中设置counter
,我们需要使用self
。因此,我们必须counter += n
而不是self.counter += n
。
最后,考虑是否希望属性从外部源可读写,或者是否要保留对象本身的写权限。因为您有方法可以向items
添加内容并增加counter
,所以您可能希望隐藏写权限。我会公开使用attr_reader
,私下使用attr_writer
。
结合这些建议,这是结果代码:
class Box
attr_reader :counter, :items
def initialize(initial_count)
@counter = initial_count
@items = []
end
def add(product)
items << product
end
def empty?
items.empty?
end
def increment(n = 1)
self.counter += n
end
private
attr_writer :counter, :items
end
现在你可以做到这一点,所有这些都有意义,或多或少:
>> cart = Box.new(123)
>> cart.increment(2)
>> cart.counter
#> 125
>> cart.add('A product')
>> cart.add('Another product')
>> cart.items
#> ["A product", "Another product"]
但如果您尝试直接设置counter
或items
,则会收到错误消息:
>> cart.counter = 1
#> NoMethodError: private method `counter=' called for #<Box:0x007fc13e17dc50>