Ruby代码块和Chef

我是Ruby和Chef的新手。 我一直试图绕过语法并做一些研究,但我相信大家都知道,除非你知道术语,否则很难找到你想要的东西。

我已经阅读了Ruby代码块,但是Chef代码块仍然让我感到困惑。 我看到这样的事情:

log "a debug string" do level :debug end 

这会在日志中添加“调试字符串”。 从我所看到的情况来看,在我看来它应该表示为:

 log do |message| #some logic end 

Chef将这些视为资源。 有人可以帮助解释语法差异并给我一些术语,我可以从中开始教育自己吗?

如果你来自另一种语言(不是Ruby),这种语法可能看起来很奇怪。 让我们分解一下。

调用带参数的方法时,在大多数情况下括号是可选的:

  • foo(bar)相当于foo bar
  • foo(bar, baz)相当于foo bar, baz

Ruby代码块可以用大括号( {} )或do..enddo..end ,可以作为最后一个参数传递给方法(但请注意,没有逗号,如果你使用括号,它会去他们之后 。一些例子:

 foo(bar) { # code here } foo(bar) do # code here end foo bar do # code here end foo do # code here end 

在某些情况下,代码块可以接收参数,但在Chef中,资源的块永远不会。 仅供参考,其语法为:

 foo(bar) do |baz, qux| baz + qux end 

特别是关于Chef资源,它们的语法通常是:

 resource_type(name) do attribute1 value1 attribute2 value2 end 

这意味着,当你说:

 log "a debug string" do level :debug end 

您实际上是在创建一个log资源,其name属性设置为"a debug string" 。 稍后可以使用log[a debug string]来引用它(例如,在其他资源中)。

AFAIK, name属性对于每个Chef资源类型都是必需的,因为它使它独特,并允许您在声明之后调用其上的操作。


附注:对于Chef资源,ruby块通常是可选的。 如果您执行以下操作:

 directory "/some/path" 

Chef将使用其默认属性(其中包括action :create )编译该资源,并尝试使用这些属性创建命名目录。

这里的do ... end不是通常的ruby块语句。

它是DSL (Domain Specific Language)

这是一个很好的解释[ 1 ]:

有一个内部DSL的概念,它使用最新语言的语法,主机语言,如Ruby。 语言的手段用于构建类似于不同语言的构造。 已经提到过,Rake使用它来制作这样的代码:

 task :codeGen do # do the code generation end 

希望能回答你的问题。

[ 1 ]: http : //www.infoq.com/news/2007/06/dsl-or-not