[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Is there a way to call include for an object instance?

Chris Olsen

7/16/2008 3:38:00 AM

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-....

5 Answers

Trans

7/16/2008 3:50:00 AM

0



On Jul 15, 11:38=A0pm, 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. =A0Is there a way to ad=
d
> an include to an object instance rather than a class?
>
> Thanks for the help
>
> ########
> module SoftballStats
> =A0 def to_sport
> =A0 =A0 puts "softball"
> =A0 end
>
> =A0 def batting_average
> =A0 =A0 0.563
> =A0 end
>
> =A0 def before_save
> =A0 =A0 puts "in the softball before save"
> =A0 end
>
> end
>
> module HockeyStats
> =A0 def to_sport
> =A0 =A0 puts "hockey"
> =A0 end
>
> =A0 def scoring_percentage
> =A0 =A0 0.34
> =A0 end
>
> =A0 def before_save
> =A0 =A0 puts "in the hockey before save"
> =A0 end
>
> end
>
> class Stats
>
> =A0 def self.create_by_sport(sport)
> =A0 =A0 s =3D Stats.new
> =A0 =A0 s.sport =3D sport
> =A0 =A0 return s
> =A0 end
>
> =A0 def sport=3D(sport)
> =A0 =A0 Stats.instance_eval do =A0# have tried to use self.instance_eval
> =A0 =A0 =A0 eval("include #{sport.capitalize}Stats")
> =A0 =A0 end
> =A0 end

Couple of ways. One is to use the singleton.

def sport=3D(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.

Chris Olsen

7/16/2008 4:08:00 AM

0

Trans wrote:
> 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.

Thanks again.
--
Posted via http://www.ruby-....

Eric I.

7/16/2008 4:11:00 AM

0

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 visit http://Lea... for all the details.

Tachikoma

7/16/2008 8:07:00 AM

0

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://LearnR... all the details.

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

Chris Olsen

7/16/2008 3:00:00 PM

0

Eric I. wrote:
> def sport=(sport)
> extend(self.class.const_get(sport.capitalize + "Stats"))
> end
>
> I believe that will work for you.

That also works well.
--
Posted via http://www.ruby-....