I would like to use “include” inside a method… something like:
class MyClass < Test::Unit::Testcase
def setup()
if $myVar.nil? then
include Mod1::Vals2
super()
end
end
is there any way?
I would like to use “include” inside a method… something like:
class MyClass < Test::Unit::Testcase
def setup()
if $myVar.nil? then
include Mod1::Vals2
super()
end
end
is there any way?
Mario R. wrote in post #1006664:
I would like to use “include” inside a method… something like:
class MyClass < Test::Unit::Testcase
def setup()
if $myVar.nil? then
include Mod1::Vals2
super()
endend
is there any way?
What are you trying to achieve?
If you want methods from Mod1::Vals2 to be included just in this
instance of MyClass which has been created, you’d use:
extend Mod1::Vals2
If you are trying to pick up different constants, then it’s probably not
going to work.
$flag = true
module Bar
WIBBLE = 2
end
class Foo
WIBBLE = 1
def setup
extend Bar if $flag
end
def doit
puts WIBBLE
puts self.class::WIBBLE
end
end
Foo.new.tap { |o| o.setup }.doit
But you could instead just do:
class Foo
if $flag
WIBBLE = 2
else
WIBBLE = 1
end
… etc
end
Brian C. wrote in post #1006721:
What are you trying to achieve?
It seems pretty obvious.
Mario R. wrote in post #1006664:
I would like to use “include” inside a method.
require “my_dog_and_cat_classes”
class Test
include Dog
end
Test.new.speak
–output:–
bark
Inside a class and outside of any method definitions, self = the class.
When a method, like include, does not have an explicit receiver
calling the method, then the implicit receiver calling the
method is self, so the line:
include Dog
is implicitly the same as:
self.include Dog
which is equivalent to:
Test.include Dog
So, lets try that explicitly:
class Test
Test.include Dog
end
Test.new.speak
–output:–
ruby.rb:3: private method `include’ called for Test:Class
(NoMethodError)
In ruby, private methods cannot be called with an explicit receiver.
Even though ruby implicitly does this:
Test.include Dog
you can’t explicitly write Test(or self) there. That is problematic
when you
write include() inside another method:
class Test
def do_stuff(arg)
if arg > 0
include Dog
else
include Cat
end
end
end
t = Test.new
t.do_stuff(-5)
Inside a def, self = the object that called the method. In this case,
that would be t. Implicitly the include statement looks like
this:
self.include Dog
and because self = t, that statement is equivalent to:
t.include Dog
but we want to include Dog in the Test class, so we have to call
Test.include. You could try writing this:
class Test
def do_stuff(arg)
if arg > 0
self.class.include Dog #self=t
else
self.class.include Cat #self=t
end
end
end
Because self = t and self.class = Test, you are really writing:
Test.include Dog
which is what you want, but include() is private, so you cannot call it
with an explicit receiver. What to do? You need to create a scope in
which self=Test, so that you can call include() without a receiver, and
the implicit receiver will be Test.
class_eval() to the rescue:
class Test
def do_stuff(arg)
if arg > 0
self.class.class_eval do
include Dog
end
else
self.class.class_eval do
include Cat
end
end
end
end
t = Test.new
t.do_stuff(-5)
t.speak
–output:–
meow
Inside the block you specify for class_eval, self = the object that
called class_eval().
7stud – wrote in post #1006724:
Brian C. wrote in post #1006721:
What are you trying to achieve?
It seems pretty obvious.
It isn’t to me. Modules have a dual purpose: they are containers for
methods that you might want to mix into another class or object, but
they also provide a namespace for constants. The name “Mod1::Vals2”
suggests to me that he could be interested in values (constants) within
that module, rather than methods.
The ‘include’ mechanism can hook into constant resolution, as well as
method inclusion. For example:
module Bar
WIBBLE = 2
end
class Foo
include Bar
puts WIBBLE # prints 2
end
But thanks for providing the detailed explanation of class_eval etc.
Thanks a lot!!!
self.class.class_eval do
was exactly what I was trying to do.
7stud – wrote in post #1006724:
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs