在哪里学习Ruby DSL


Vagrant.configure(2) do |config|
  config.vm.define "chefnode" do |chefnode|
    chefnode.vm.box = "geerlingguy/ubuntu1604"
    chefnode.vm.hostname = 'cnode'
    chefnode.vm.network "public_network"
  end
  config.vm.define "chefserver" do |chefserver|
    chefserver.vm.box = "geerlingguy/ubuntu1604"
    chefserver.vm.hostname = 'cserver'
    chefserver.vm.network "public_network"
  end
end

我在上述(流浪 dsl)代码上苦苦挣扎。这是Ruby DSL还是普通Ruby或其他东西?为什么 vm.box 和 vm.hostname 有"="符号,而 vm.network 没有?

首先是

Ruby,当你想创建自己的DSL时,作为一种语言,它非常方便。所有的DSL都是使用基本的红宝石概念构建的,比如块(do ... end)——这里没有魔法。在您的情况下,我们可能会说它是由流浪者所有者创建的DSL。

为什么他们曾经使用=而另一次不使用?在这种特定情况下,我假设这是由您有一个参数引起的,该参数是字符串并且是必需的,稍后 yo 可能会传递具有不同设置选项的哈希值,例如文档中的示例。

Vagrant.configure("2") do |config|
  config.vm.network "forwarded_port", guest: 80, host: 8080
end

如果他们想使用=他们将不得不强制您传递一个需要名称键的哈希,其余的将是可选的,我的意思是这样的:

config.vm.network = { name: "default" }

这是标准的Ruby,这里没有DSL或元编程魔法。

Ruby 在这方面很不寻常,但以下都是对 chefserver.vm 返回的对象调用方法:

chefserver.vm.hostname = 'chefserver'  # calls method 'hostname='
chefserver.vm.network "public_network" # calls method 'network'

Ruby 不需要在方法调用中使用括号(尽管有时它们对于向解释器澄清你的意思是必要的)。

我不认识 Chef,所以我不能说为什么network调用不network=,除了在 Ruby 中调用名称以"="结尾且参数超过 1 个的方法不起作用。 尽管这里只指定了 1 个要network的参数,但在 Ruby 中可以有可选参数。该方法可能被定义为如下:

def network(name, something = 'foo')
  # ...
end

。以便可以使用 1 或 2 个参数调用该方法。

最新更新