2

I am an extremely new person to Ruby and Chef. I have been trying to wrap my head around the syntax and do some research, but I am sure as you all know unless one knows the terminology, it is hard to find what you are looking for.

I have read up on Ruby code blocks, but the Chef code blocks still confuse me. I see something like this for example:

log "a debug string" do
    level :debug
end

Which adds "a debug string" to the log. From what I have seen though, it seems to me like it should be represented as:

log do |message|
    #some logic
end

Chef refers to these as resources. Can someone please help explain the syntax difference and give me some terminology from which I can start to educate myself with?

4

2 回答 2

6

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

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

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

Ruby 代码块可以包裹在花括号 ( {}) 中或do..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)编译该资源,并尝试使用这些属性创建命名目录。

于 2013-11-01T12:25:34.813 回答
1

这里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

于 2013-11-01T07:59:08.400 回答