Ruby on Rails 3,创建新对象时出现语法错误

时间:2011-08-17 17:24:40

标签: ruby ruby-on-rails-3

我还在学习Ruby,并且仍然从我的手册中复制粘贴。但我遇到了一个问题,我不知道如何解释,我做错了什么。所以这里是: 我想用这个创建一个新对象:

second_page = Page.new ( :name=>"Second page", :position=>1, :permalink => "second" )

我收到了一个错误:

Loading development environment (Rails 3.0.10)
ruby-1.9.2-p290 :001 > second_page = Page.new ( :name=>"Second page", :position=>1, :permalink => "second" )
SyntaxError: (irb):1: syntax error, unexpected tASSOC, expecting ')'
...econd_page = Page.new ( :name=>"Second page", :position=>1, ...
...                               ^
(irb):1: syntax error, unexpected ',', expecting $end
...age.new ( :name=>"Second page", :position=>1, :permalink => ...
...                               ^
        from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/railties-3.0.10/lib/rails/commands/console.rb:44:in `start'
        from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/railties-3.0.10/lib/rails/commands/console.rb:8:in `start'
        from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/railties-3.0.10/lib/rails/commands.rb:23:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

但是,如果我这样做:

ruby-1.9.2-p290 :002 > second_page = Page.new  :name=>"Second page", :position=>1, :permalink => "second"
 => #<Page id: nil, subject_id: nil, name: "Second page", permalink: "second", position: 1, visible: false, created_at: nil, updated_at: nil>

似乎有效。 我从手册中得到了例子,我想知道发生了什么? 没有()我不知道我怎么能用那个对象做什么? 谢谢

3 个答案:

答案 0 :(得分:1)

如果您选择放置空格,Ruby不允许您在圆括号之前放置空格。这应该有效:

second_page = Page.new( :name=>"Second page", :position=>1, :permalink => "second" )

答案 1 :(得分:1)

这里有解析器试图解决语法歧义。 Page.new接受一个参数:包含应在新创建的活动记录对象上设置的属性的哈希。

如果现在调用方法而没有任何括号,则最初不清楚参数是什么。因此,解析器足够聪明,可以确定在这种情况下它应该是一个哈希值。

如果你实际上写了括号,你必须更具体一点,并且必须实际写下哈希大括号。因此,以下陈述是等效的:

first_page = Page.new :foo => "Bar"
second_page = Page.new({:foo => "Bar"})
third_page = Page.new ({:foo => "Bar"})

在大多数情况下,括号在Ruby中的方法调用中是可选的。但只有在没有任何含糊之处的情况下。如有疑问,请始终指定括号。请注意,Ruby 1.9在此更改了语法,因此更加严格。

答案 2 :(得分:1)

在ruby括号中,方法参数不是必需的。所以,

 object.method()
 # is same as
 object.method

 object.method(param1, param2)
 # is same as 
 object.method param1, param2

传递任意数量的参数还有另一种流行的语法:

def print_a(*params)
  puts params.inspect
end

print_a "a"                                  
#prints: ["a"]

print_a "a", "b"                             
#prints: ["a", "b"]

print_a "a", "b", 2, :four => 4              
#prints: ["a", "b", 2, {:four=>4}]

print_a "a", "b", 3, :four => 4, :five => 5  
#prints: ["a", "b", 3, {:four=>4, :five=>5}]

正如您在上一个示例中所注意到的,ruby足够智能,可以检测哈希并在单个哈希参数中聚合键值对。但它只有在散列是最后一个参数时才有效。

 print_a("a", "b", :four => 4, :five => 5, 3)
 # gives error: syntax error, unexpected '\n', expecting tASSOC

 # converting the hash to an explicit hash works again
 print_a "a", "b", {:four => 4, :five => 5}, 3
 # ["a", "b", {:four=>4, :five=>5}, 3]