Ruby多行块无需结束

时间:2010-09-09 19:54:44

标签: ruby

我是Ruby的初学者,所以很抱歉问这么简单,但是这段代码有什么问题 -

3.upto(9) {
  print "Hello"
  puts " World"
}

3.upto(9) { |n|
  print "Hello "
  puts n
}

它运行良好,但我看到的大多数代码示例都使用

的语法
3.upto(9) do |n|
  print "Hello "
  puts n
end

只是对单个语句使用花括号的约定?来自C / C#的第一个似乎对我来说更自然,但是在罗马时!

3 个答案:

答案 0 :(得分:43)

两种语法之间存在细微差别。 { }的优先级高于do ... end。因此,以下内容将bar和一个块传递给方法foo

foo bar do ... end

而以下内容会将一个块传递给bar,并将结果传递给foo

foo bar { ... }

因此,您的示例将采取相同的行动。但是,如果你离开括号:

> 3.upto 9 { 
  puts "Hi" 
}
SyntaxError: compile error
(irb):82: syntax error, unexpected '{', expecting $end
3.upto 9 { 
          ^
    from (irb):82
    from :0

> 3.upto 9 do 
    puts "Hi" 
  end
Hi
Hi
Hi
Hi
Hi
Hi
Hi
=> 3

所以,如果你在Ruby中放弃括号,{ }更容易引起你的注意,这是相当常见的;由于这个原因,并且因为Ruby条件和其他控件构造都使用end作为分隔符,人们通常会使用do ... end来表示语句末尾的多行代码块。

但是,{ }经常用于do ... end会很麻烦的地方,例如,如果你将几个方法链接在一起就会占用块。这可以让你编写一个简短的一行小块,可以用作方法链的一部分。

> [1,2,3].sort{|x,y| y<=>x}.map{|x| x+1}
=> [4, 3, 2]

以下是一个说明这种差异的例子:

def foo arg
  if block_given?
    puts "Block given to foo"
    yield arg
  else
    puts "No block given to foo"
    arg
  end
end


def bar
  if block_given?
    puts "Block given to bar"
    yield "Yielded from bar"
  else
    puts "No block given to bar"
  end
  "Returned from bar"
end

irb(main):077:0> foo bar { |arg| puts arg }
Block given to bar
Yielded from bar
No block given to foo
=> "Returned from bar"
irb(main):078:0> foo bar do |arg| puts arg end
No block given to bar
Block given to foo
Returned from bar
=> nil

答案 1 :(得分:7)

这只是惯例。

答案 2 :(得分:0)

seamless。来自README

  

Python允许您通过缩进来表示代码块的结尾。 Ruby遭受了一个非常冗长乏味的块终止符,&#34; end&#34;。就像Lisps最终得到了几十个密切关注的那样,使用模块和类的Ruby文件最终会导致过多的结果和#34;这不是必要的。

     

编写一个Ruby文件,但跳过所有&#34;结束&#34;。像在Python中一样排列代码块。然后只需将其命名为“your_file.rbe”,要求“无缝”,并要求“你的文件”。其余的都是无缝的。

     

这应该广泛使用吗?我不知道。但它很有趣!