2015-02-07 55 views
4

例如,在Rails的Gemfile:`do` ...`end`语句如何在没有阻塞参数的情况下工作?

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

正在发生的事情与do ... end声明?并使用RSpec:

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

do ... end -s创建块被其它地方使用其信息在两者之间?如何在没有设置块参数的情况下工作?

+0

一个简单但常见的使用块没有块变量的例子是初始化一个二维数组:Array.new 5 do; [];结束#=> [[],[],[],[],[]]'。你可以编写'do | i | []; end',但是Ruby不介意如果你不需要它的话就丢弃块变量。 – 2015-02-07 07:49:05

回答

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

+0

谢谢你指点我正确的方向!我已经阅读了两次,可能需要再次多读几遍,但是很好的资源! ++ – Frank 2015-02-07 09:02:34

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."} 
相关问题