I need to be able to create an object and, based on the param that I
pass in on the class create_for_sport method, create an object with the
proper module included.
It can be seen at the bottom by the comments I made that the includes
are being added on to the Stats class and the methods from the first
include are still there after the second include. Is there a way to add
an include to an object instance rather than a class?
Thanks for the help
···
########
module SoftballStats
def to_sport
puts "softball"
end
def batting_average
0.563
end
def before_save
puts "in the softball before save"
end
end
module HockeyStats
def to_sport
puts "hockey"
end
def scoring_percentage
0.34
end
def before_save
puts "in the hockey before save"
end
end
class Stats
def self.create_by_sport(sport)
s = Stats.new
s.sport = sport
return s
end
def sport=(sport)
Stats.instance_eval do # have tried to use self.instance_eval
eval("include #{sport.capitalize}Stats")
end
end
end
s = Stats.create_by_sport("softball")
puts s.batting_average # 0.563
h = Stats.create_by_sport("hockey")
puts h.scoring_percentage # 0.34
puts h.batting_average # 0.563 -> still has this method
s.before_save # "in the hockey save" -> softball before_save is now
overridden
h.before_save # "in the hockey save"
--
Posted via http://www.ruby-forum.com/.
def sport=(sport)
(class << self; self; end).class_eval %{
include #{sport.capitalize}Stats
}
end
But I think you might want to reconsider and use delegation instead.
T.
···
On Jul 15, 11:38 pm, Chris Olsen <olsen.ch...@gmail.com> wrote:
I need to be able to create an object and, based on the param that I
pass in on the class create_for_sport method, create an object with the
proper module included.
It can be seen at the bottom by the comments I made that the includes
are being added on to the Stats class and the methods from the first
include are still there after the second include. Is there a way to add
an include to an object instance rather than a class?
Thanks for the help
########
module SoftballStats
def to_sport
puts "softball"
end
def batting_average
0.563
end
def before_save
puts "in the softball before save"
end
end
module HockeyStats
def to_sport
puts "hockey"
end
def scoring_percentage
0.34
end
def before_save
puts "in the hockey before save"
end
end
class Stats
def self.create_by_sport(sport)
s = Stats.new
s.sport = sport
return s
end
def sport=(sport)
Stats.instance_eval do # have tried to use self.instance_eval
eval("include #{sport.capitalize}Stats")
end
end
I need to be able to create an object and, based on the param that I
pass in on the class create_for_sport method, create an object with the
proper module included.
You can call extend on an instance to mix in a modules instance
methods to the instance (and leaving the class itself alone). In your
code, we also need to convert your string to a reference to the module
as well, via a call to const_get. And this would be your new sport=
method:
def sport=(sport)
extend(self.class.const_get(sport.capitalize + "Stats"))
end
I believe that will work for you.
Eric
···
====
LearnRuby.com offers Rails & Ruby HANDS-ON public & ON-SITE workshops.
Please visit http://LearnRuby.com for all the details.
On Jul 15, 11:38�pm, Chris Olsen <olsen.ch...@gmail.com> wrote:
� def before_save
� def scoring_percentage
� end
Couple of ways. One is to use the singleton.
def sport=(sport)
(class << self; self; end).class_eval %{
include #{sport.capitalize}Stats
}
end
But I think you might want to reconsider and use delegation instead.
T.
Thanks so much. To be honest I have no idea what the (class << self;
self; end), but it will make for good reading :). I will look into the
delegation as well.
you should put module(s) into class ,to ensure class Stats has the
permission of module,so try following code
class Stats
module HockeyStats
def to_sport
puts "hockey"
end
def scoring_percentage
0.34
end
def before_save
puts "in the hockey before save"
end
end
module SoftballStats
def to_sport
puts "softball"
end
def batting_average
0.563
end
def before_save
puts "in the softball before save"
end
end
def self.create_by_sport(sport)
s = Stats.new
s.sport = sport
return s
end
def sport=(sport)
eval "extend #{sport.to_s.capitalize}Stats"
end
end
···
On Jul 16, 12:11 pm, "Eric I." <rubytrain...@gmail.com> wrote:
Hi Chris,
> I need to be able to create an object and, based on the param that I
> pass in on the class create_for_sport method, create an object with the
> proper module included.
You can call extend on an instance to mix in a modules instance
methods to the instance (and leaving the class itself alone). In your
code, we also need to convert your string to a reference to the module
as well, via a call to const_get. And this would be your new sport=
method:
def sport=(sport)
extend(self.class.const_get(sport.capitalize + "Stats"))
end
I believe that will work for you.
Eric
====
LearnRuby.com offers Rails & Ruby HANDS-ON public & ON-SITE workshops.
Please visithttp://LearnRuby.comfor all the details.