Reputation: 6102
For example, I have a class that defined a instance variable:
class ApplicationApi < Grape::API
include WithGrapeLogging
@api_environment_name = "Android"
end
Here is my custom module, in this custom module, I called instance variable of above class:
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
I don't know what that variable is null. Please figure me how.
Upvotes: 1
Views: 163
Reputation: 1666
Let's take a look at the Module#include
method's source code:
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;
}
We can see that for each of the arguments passed to Module#include
, it calls the block passed to included
(via rb_funcall
)
When you include
your module on the second line of your class definition, it calls the block provided to included
in your module definition. When it's running through that block, Ruby identifies that @api_environment_name
has not been defined and throws an error. If you put the definition of that instance variable before you include
the module, it will recognize it.
Upvotes: 1