`do` ...`end`语句如何在没有块参数的情况下工作?

时间:2015-02-07 04:37:24

标签: ruby codeblocks local-variables

例如,在Rails gemfile中:

group :development, :test do
  gem 'rspec-rails', '~> 2.0'
end

do ... end声明发生了什么?并使用rspec:

describe "Foo" do
  context "bar" do
     expect...
  end
end

do ... end - 创建一个块,其间的信息正在其他地方使用?如果没有设置块参数,它如何工作?

2 个答案:

答案 0 :(得分:5)

这称为特定领域语言

  

领域特定语言(DSL)是“专注于特定领域的表达能力有限的编程语言”。通过删除特定任务的无关代码并允许您专注于手头的特定任务,它可以使其域中的任务更容易。它还可以帮助其他人阅读代码,因为代码的目的非常明确。

基本上这个

group :development, :test do
  gem 'rspec-rails', '~> 2.0'
end

只是调用带有参数group和块:development, :test的方法gem 'rspec-rails', '~> 2.0'Which is defined in this way in Bundler DSL

def group(*args, &blk)
  ...
end

第二个例子也是如此。

  

DSL定义了对示例进行分组的方法,最明显的是描述,并将它们公开为RSpec的类方法。

.describe is being implemented in this way

def describe(doc_string, *metadata_keys, metadata = {}, &example_implementation)
  ...
end

您可以阅读有关在Ruby in this thoughtbot.com article

中编写特定于域的语言的更多信息

答案 1 :(得分:2)

接收块参数是可选的。如果您不使用块变量,即使使用块变量调用块,也不必编写|...|

def foo &block
  block.call(:foo)
end

foo{|v| puts "I received `:foo', but am not using it."}
foo{puts "I am called with `:foo', but am not receiving it."}

如果定义的方法不传递任何块变量,那么块中不需要|...|

def bar &block
  block.call
end

bar{puts "I am not called with a block variable in the first place."}