包含的模块不能调用父类的实例变量

时间:2017-06-08 13:46:44

标签: ruby-on-rails ruby

例如,我有一个定义实例变量的类:

 class ApplicationApi < Grape::API
    include WithGrapeLogging
    @api_environment_name = "Android"
  end

这是我的自定义模块,在这个自定义模块中,我调用了上面的类的实例变量:

require 'grape_logging'
module WithGrapeLogging
  extend ActiveSupport::Concern
  included do
      logger.formatter = GrapeLogging::Formatters::Default.new

      use GrapeLogging::Middleware::RequestLogger,
        logger: logger,
        formatter: GrapeLoggerFormatter.new(@api_environment_name),
        include: [ GrapeLogging::Loggers::Response.new,
                   GrapeLogging::Loggers::FilterParameters.new,
                   GrapeLogging::Loggers::ClientEnv.new,
                   GrapeLogging::Loggers::RequestHeaders.new ]
  end
end

我不知道该变量是什么。请告诉我如何。

1 个答案:

答案 0 :(得分:1)

让我们来看看Module#include方法的源代码:

               static VALUE
rb_mod_include(int argc, VALUE *argv, VALUE module)
{
    int i;
    ID id_append_features, id_included;

    CONST_ID(id_append_features, "append_features");
    CONST_ID(id_included, "included");

    for (i = 0; i < argc; i++)
        Check_Type(argv[i], T_MODULE);
    while (argc--) {
        rb_funcall(argv[argc], id_append_features, 1, module);
        rb_funcall(argv[argc], id_included, 1, module);
    }
    return module;
}

我们可以看到,对于传递给Module#include的每个参数,它会调用传递给included的块(通过rb_funcall

当您在类定义的第二行include模块时,它会调用模块定义中提供给included的块。当它运行该块时,Ruby会识别出@api_environment_name尚未定义并抛出错误。如果你将之前的实例变量的定义放在模块的include之内,它就会识别它。