我为User定义了一个类,它将哈希作为参数, 类用户 attr_accessor:name,:email
def initialize(attributes = {})
@name = attributes[:name]
@email = attributes[:email]
end
def formatted_email
"#{@name} <#{@email}>"
end
end
在使用括号和参数的空格语法在控制台中初始化时,行为是不同的,第二个没有接收属性,但如果我先定义一个哈希然后用哈希作为参数初始化,它现在运作良好,为什么会发生这种情况?
2.0.0-p451 :013 > example = User.new(name:'John', email:'john@example.com')
=> #<User:0x007fbcdb57e140 @name="John", @email="john@example.com">
2.0.0-p451 :014 > example = User.new {name:'John', email:'john@example.com'}
=> #<User:0x007fbcdb599080 @name=nil, @email=nil>
2.0.0-p451 :021 > hash = {name: 'John', email: 'john@example.com'}
=> {:name=>"John", :email=>"john@example.com"}
2.0.0-p451 :022 > User.new hash
=> #<User:0x007fbcdc4af8a8 @name="John", @email="john@example.com">
答案 0 :(得分:3)
查看代码:
class User
def initialize(attributes = {})
p attributes # I put it to debug the hash **attributes** after each *new* call.
@name = attributes[:name]
@email = attributes[:email]
end
def formatted_email
"#{@name} <#{@email}>"
end
end
# here you did pass the method argument as a Hash.
User.new(name:'John', email:'john@example.com')
# >> {:name=>"John", :email=>"john@example.com"} # output of attributes hash
# you got #<User:0x007fbcdb57e140 @name="John", @email="john@example.com">, as the
# hash **attributes** is, {:name=>"John", :email=>"john@example.com"}. So inside the
# initialize method
# @name = "John" as , attributes[:name] is "John"
# @email = "john@example.com" as, attributes[:email] is "john@example.com"
# here you didn't pass the method argument as a Hash, rather a block.
User.new {name:'John', email:'john@example.com'}
# >> {} # output of attributes hash is empty hash.
# you got #<User:0x007fbcdb599080 @name=nil, @email=nil>, as *attributes* is empty.
# so inside the initialize method @name = nil happened, as attributes[:name] is nil.
# @email = nil, as attributes[:email] is nil.
# here you did pass the method argument as a Hash.
hash = {name: 'John', email: 'john@example.com'}
User.new hash # output of attributes hash
# >> {:name=>"John", :email=>"john@example.com"}
在Ruby中,调用语法的方法是
meth_name(argument_list_of_object/objects) { #block }
meth_name(argument_list_of_object/objects)
meth_name argument_list_of_object/objects
。当你没有传递阻止时这是有效的,否则错误将被删除这意味着在Ruby中,{ .. }
在方法调用之后,解析为好像,您正在向方法发送一个块,而不是像将 hash 作为参数传递一样。
说明这一理论的另一个简单例子:
def foo(arg = 10)
p arg
end
foo 12 # => 12
foo(12) # => 12
foo { 12 } # => 10 default value
foo "arg" { 12 }
# ~> -:8: syntax error, unexpected '{', expecting end-of-input
# ~> foo "arg" { 12 }
# ~>
总结:
# you are passing a 2 key/value argument, which in runtime will create a hash
# {name:'John', email:'john@example.com'}, then will be assigned to
# local variable attributes of the method initialize.
User.new name:'John', email:'john@example.com'
# => #<User:0x90f5a24 @email="john@example.com", @name="John">
# same as above
User.new(name:'John', email:'john@example.com')
# => #<User:0x90f4a5c @email="john@example.com", @name="John">
# simply passing a block to the method.
User.new {name:'John', email:'john@example.com'}
# => #<User:0x90f7450 @email=nil, @name=nil>
希望这有帮助。
答案 1 :(得分:0)
这是由于空白空间,以下应打印正确,我已删除空格并添加括号
example = User.new({name: 'John', email: 'john@example.com'})