1

我正在尝试使用 Thor::Actions 模板方法来生成一些 C++ 测试文件模板,但 erb 一直告诉我我有未定义的变量和方法。

这是调用代码:

def test (name, dir)
  template "tasks/templates/new_test_file", "src/#{dir}/test/#{name}Test.cpp"
  insert_into_file "src/#{dir}/test/CMakeLists.txt", 
       "#{dir}/test/#{name}Test ", :after => "set(Local "
end

这是模板:

<% test_name = name + "Test" %>
#include <gtest/gtest.h>
#include "<%= dir %>/<%= name %>.h"

class <%= test_name %> : public testing::Test {
protected:
    <%= test_name %> () {}
    ~<%= test_name %> () {}
    virtual void SetUp () {}
    virtual void TearDown () {}
};

// Don't forget to write your tests before you write your implementation!
TEST_F (<%= test_name %>, Sample) {
   ASSERT_EQ(1 + 1, 3);
}

我该怎么做才能将名称和目录纳入此处?我有更复杂的模板,我也需要这个功能。

4

2 回答 2

4

我意识到您已经解决了这个问题,但是我发布了这个答案,以防其他人出现在寻找您提出的问题的解决方案(就像一样)。

在#test 所属的类中,创建一个attr_accessor,然后在调用模板的同一方法中设置其值。

class MyGenerator < Thor

  attr_accessor :name, :dir

  def test (name, dir)
    self.name = name
    self.dir = dir
    template "tasks/templates/new_test_file", "src/#{dir}/test/#{name}Test.cpp"
  end
end

注意:如果您使用#invoke 链接方法,则每次调用都将使用该类的新实例。因此,您必须使用模板调用在方法中设置实例变量。例如,以下将不起作用。

class MyGenerator < Thor

  attr_accessor :name

  def one (name)
    self.name = name
    invoke :two
  end

  def two (name)
    # by the time we get here, this is another instance of MyGenerator, so @name is empty
    template "tasks/templates/new_test_file", "src/#{name}Test.cpp"
  end

end

你应该把self.name = name#two 放在里面

为了制作生成器,如果您从 Thor::Group 继承,则所有方法都会按顺序调用,并且将为您设置 attr_accessor 并为每个方法设置实例变量。就我而言,我不得不使用 Invocations 而不是 Thor::Group,因为我无法让 Thor::Group 类被识别为可执行文件的子命令。

于 2012-02-19T09:33:20.993 回答
2

ERB 使用 ruby​​ 的绑定对象来检索您想要的变量。ruby 中的每个对象都有一个绑定,但默认情况下,对绑定的访问仅限于对象本身。您可以解决此问题,并将您希望的绑定传递到您的 ERB 模板中,方法是创建一个公开对象绑定的模块,如下所示:

module GetBinding
  def get_binding
    binding
  end
end

然后,您需要使用此模块扩展具有所需变量的任何对象。

something.extend GetBinding

并将该对象的绑定传递给 erb

something.extend GetBinding
some_binding = something.get_binding

erb = ERB.new template
output = erb.result(some_binding)

有关使用 ERB 的完整示例,请参阅我的一个项目的 wiki 页面:https ://github.com/derickbailey/Albacore/wiki/Custom-Tasks

于 2011-07-08T20:28:54.660 回答