Ruby 代码块和 Chef

Posted

技术标签:

【中文标题】Ruby 代码块和 Chef【英文标题】:Ruby code blocks and Chef 【发布时间】:2013-11-12 06:04:05 【问题描述】:

对于 Ruby 和 Chef,我是一个非常陌生的人。我一直在尝试围绕语法进行一些研究,但我相信你们都知道,除非有人知道术语,否则很难找到您要查找的内容。

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

log "a debug string" do
    level :debug
end

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

log do |message|
    #some logic
end

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

【问题讨论】:

【参考方案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

【讨论】:

【参考方案2】:

如果您来自其他语言(不是 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 资源类型都是必需的,因为它使它独一无二,并且允许您在声明它之后对其调用操作。


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

directory "/some/path"

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

【讨论】:

以上是关于Ruby 代码块和 Chef的主要内容,如果未能解决你的问题,请参考以下文章

代码块和并发性

代码块和作用域

Ruby 中的块和产量

静态代码块和实例化代码块

两个案例,解读静态代码块和构造代码块

Java 重学系列之匿名代码块和静态代码块区别