Robert Klemme
7/9/2006 5:26:00 PM
Damaris Fuentes wrote:
> Ok, thanks for the explanations!
> But...now that you mention the concatenator... I will comment another
> problem in this entry. (I write all the code, ven though perhaps you
> don't need it)
>
> The problem here is that the re- definition ot a class (LotteryDraw)
> doesn't seem to see the attributes of the first definition.
>
> I have the class ot the lottery ticket:
> ***********************
> class LotteryTicket
> NUMERIC_RANGE = 1..25
> attr_reader :picks
>
> def initialize( *picks )
> [...]
> @picks = picks
> end
>
> def score( final )
> count = 0
> final.picks.each do |note|
> count +=1 if picks.include? note
> end
> count
> end
>
> end
>
> *****************************
> Now I have the lottery draw, where I store the buyers of the tickets:
> **********************
> class LotteryDraw
> @@tickets = {}
> def LotteryDraw.buy( customer, *tickets )
> unless @@tickets.has_key?( customer )
> @@tickets[customer] = []
> end
> @@tickets[customer] += tickets
> end
> end
> *******
> And NOW, I REDEFINE THE CLASS with the concatenator, adding a new class
> method:
> ********************
> class << LotteryDraw
> def play
> final = LotteryTicket.new_random
> winners = {}
> @@tickets.each do |buyer, ticket_list|
> ticket_list.each do |ticket|
> score = ticket.score( final )
> next if score.zero?
> winners[buyer] ||= []
> winners[buyer] << [ ticket, score ]
> end
> end
> @@tickets.clear
> winners
> end
> end
> ********
>
> And now I execute the following:
> ************************
> LotteryDraw.buy('JuanMi',
> LotteryTicket.new( 12, 6, 19 ),
> LotteryTicket.new( 5, 1, 3 ),
> LotteryTicket.new( 24, 6, 8 ))
>
> LotteryDraw.buy('Da',
> LotteryTicket.new( 18, 4, 7 ),
> LotteryTicket.new( 21, 25, 3 ),
> LotteryTicket.new( 12, 17, 19 ))
>
> LotteryDraw.play.each do |winner, tickets|
> puts winner + "won on " + tickets.length + " ticket(s)!"
> tickets.each do |ticket, score|
> puts "\t" + ticket.picks.join( ', ' ) + ": " + score
> end
> end
> ************************************
>
> And an exception arises:
> in `play': uninitialized class variable @@tickets in Object.
> This exception appears in the trace:
> - LotteryDraw.play.each do |winner, tickets|,
> - @@tickets.each do |buyer, ticket_list| (in LotteryDraw.play)
>
> What is the problem? Thanks (and sorry if this is very long :()
>
Without looking too closely at your code I'm guessing that it's because
your class methods are in the singleton class of LotteryDraw - and so
lookups for class variables are done in *that* hierarchy and not in the
one of LotteryDraw.
I generally recommend to not use class variables because they introduce
all sorts of weirdnesses. I'd rather use a normal instance variable of
the class instance. That's accessible for sure in the singleton method.
Kind regards
robert