To generate mocks for Omniauth, I Added this method to config/environments/development.rb
def provides_mocks_for(*providers)
providers.each do |provider|
class_eval %Q{
OmniAuth.config.add_mock(provider, {
:uid => '123456',
:provider => provider,
:nickname => 'nickname',
:info => {
'email' => "#{provider}@webs.com",
'name' => 'full_name_' + provider
}
})
}
end
end
then I call in the same file:
provides_mocks_for :facebook, :twitter, :github, :meetup
But I get:
3.1.3/lib/active_support/core_ext/kernel/singleton_class.rb:11:in `class_eval': can't create instance of singleton class (TypeError)
class_eval
andmodule_eval
(which are equivalent) are used to evaluate and immediately execute strings as Ruby code. As such they can be used as a meta-programming facility to dynamically create methods. An example isIt will create two methods
foo
andbar
which print their respective values. As you can see, I create a string containing the actual source code of the function and pass it intoclass_eval
.While this is a very capable instrument of executing dynamically created code, it must be used with great care. If you make errors here, BAD THINGS WILL HAPPEN™. E.g. if you use user-supplied values when generating code, make really sure the variables contain only values you expect. Eval-based function should generally be used as the last resort.
A cleaner and generally preferred variant is to use
define_method
like so:(Note that MRI is a wee bit faster with the eval variant. But that doesn't matter most of the time when compared to the added safety and clarity.)
Now in your given code, you effectively write code into a string that can be run directly. Using
class_eval
here leads to the string being executed in the context of the top-most object (Kernel
in this case). As this is a special singleton object which can't be instanciated (similar to nil, true and false), you get this error.However, as you create directly executable code, you don't need to use
class_eval
(or any form of eval) at all. Just run your code in a loop as is. And always remember: meta-programming variants (of which the eval methods are among the most bad-ass) should only be used as the last resort.