【问题标题】:How this one attribute here hold multiple attribute in ruby class?这里的这一属性如何在 ruby 类中包含多个属性?
【发布时间】:2017-09-02 02:07:55
【问题描述】:
如您所见,我们有一个名为“attributes”的属性,我们在类中对其进行了初始化,所以问题是名称和衬衫属性从何而来,因为我们没有在类中初始化和定义它们?
class Shirt
attr_accessor :attribute
def initialize(attributes)
@attributes = attributes
end
end
store = Shirt.new(name: "go", size: "42")
当我检查这个衬衫类的实例时,我得到一个哈希:
@attributes={:name=>"go", :size=>"42"}
谁能帮忙解释一下?
【问题讨论】:
标签:
ruby
class
attributes
initialization
ruby-hash
【解决方案1】:
在 Ruby 中,如果正确定义,最后一个参数会自动解释为一个哈希值,并且您可以在没有 {} 的情况下传递它。由于只有一个参数,因此它也被视为最后一个参数:
store = Shirt.new(name: "go", size: "42")
#=> #<Shirt:0x000000022275c0 @attribute={:name=>"go", :size=>"42"}>
等同于:
store = Shirt.new({name: "go", size: "42"})
#=> #<Shirt:0x000000022271d8 @attribute={:name=>"go", :size=>"42"}>
【讨论】:
-
对于 Ruby 2.7,此隐式哈希属性会生成警告,而对于 Ruby 3,则会生成错误。较新版本的 Ruby 不允许隐式传递哈希作为方法的最后一个参数。您必须使用双 splat 运算符显式地期望和调用方法。 Reference
【解决方案2】:
@attributes={:name=>"go", :size=>"42"}
这一行告诉你的是你有一个名为@attributes的实例变量,它的值是一个哈希{:name=>"go", :size=>"42"}
用两个简单的变量来看看区别
class A
def initialize(dogs, cats)
@dogs = dogs
@cats = cats
end
end
A.new(4, 5)
=> #<A:0x007f96830e3c80 @dogs=4, @cats=5>
【解决方案3】:
指令attr_accessor :attribute定义2个方法
def attribute; @attribute;end
和
def attribute=(value); @attribute=value;end
但是当你输入
store = Shirt.new(name: "go", size: "42") 您定义了一个哈希并将其传递给属性s 参数:
init_values={name: "go", size: "42"}
store = Shirt.new(init_values)
在initialize方法中,attributes参数被当作一个Hash并传递给@attributes实例变量
尝试检查
store = Shirt.new(["go","42"])
store = Shirt.new({})
ps.
试试attr_accessor :attributes,然后你就可以使用了
store.attributes
store.attributes=