首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DRY DRY食谱

DRY DRY食谱
EN

Stack Overflow用户
提问于 2013-03-24 12:25:37
回答 2查看 8.2K关注 0票数 17

在厨师食谱中做一点烘干的最好方法是什么?也就是说,只是打破了Ruby代码的一小部分,所以我不会一遍又一遍地复制粘贴它。

当然,下面的代码会失败,因为:

代码语言:javascript
复制
NoMethodError: undefined method `connect_root' for Chef::Resource::RubyBlock

我可能在一个配方中有多个ruby_blocks,因为它们做不同的事情,需要有不同的not_if块才能成为真正的幂等块。

代码语言:javascript
复制
def connect_root(root_password)
  m = Mysql.new("localhost", "root", root_password)
  begin
    yield m
  ensure
    m.close
  end
end

ruby_block "set readonly" do
  block do
    connect_root node[:mysql][:server_root_password] do |connection|
      command = 'SET GLOBAL read_only = ON'
      Chef::Log.info "#{command}"
      connection.query(command)
    end
  end
  not_if do
    ro = nil
    connect_root node[:mysql][:server_root_password] do |connection|
      connection.query("SELECT @@read_only as ro") {|r| r.each_hash {|h| 
        ro = h['ro']
      } }
    end
    ro
  end
end
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-28 04:38:43

正如您已经了解到的,您不能在配方中定义函数。为此,提供了库。您应该在您的食谱中的文件夹中创建一个包含以下内容的文件(例如mysql_helper.rb ):

代码语言:javascript
复制
module MysqlHelper
  def self.connect_root( root_password )
    m = Mysql.new("localhost", "root", root_password)
    begin
      yield m
    ensure
      m.close
    end
  end
end

It 必须是一个模块,而不是一个类。另请注意,我们将其定义为静态(使用self.method_name)。然后,您将能够使用模块名称和方法名称在您的配方中使用此模块中定义的函数:

代码语言:javascript
复制
MysqlHelper.connect_root node[:mysql][:server_root_password] do |connection|
  [...]
end
票数 25
EN

Stack Overflow用户

发布于 2013-03-24 13:02:46

根据记录,我刚刚创建了一个包含以下内容的库。但对于一个文件中的DRY来说,这似乎有点过头了。我也不知道如何让模块使用其他的命名空间来工作。

代码语言:javascript
复制
class Chef
  class Resource
    def connect_root(root_password)
      ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15595144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档