Help! Newb having trouble getting a WHY'S example to work

Hey, I've been an avid reader of the Why's Poignant Guide to Ruby ever since
I discovered it (poignantguide.net), but while the material is excellent, it
is reduced in effectiveness because I'm reasonably certain that the writer
doesn't run (verbatim anyway) the code that he puts in some of the
tutorials. Namely, I'm having trouble getting a "lottery" tutorial to work,
and I'm too much of a Newb to see easily what the problem is. When I run the
code I get an error like so: "warning: class variable access from toplevel
singleton method"

My code is below, would anyone mind please skimming it and letting me know
what the errant code is? I appreciate it!

Regards, Abe

p.s. the code below is verbatim from the guide itself - I thought that
perhaps I'd mistyped something and so I copied and pasted the code into
Mondrian (the IDE I'm using)

class LotteryTicket

    NUMERIC_RANGE = 1..25

    attr_reader :picks, :purchased

    def initialize( *picks )

      if picks.length != 3

        raise ArgumentError, "three numbers must be picked"

      elsif picks.uniq.length != 3

        raise ArgumentError, "the three picks must be different numbers"

      elsif picks.detect { |p| not NUMERIC_RANGE === p }

        raise ArgumentError, "the three picks must be numbers between 1 and
25."

      end

      @picks = picks

      @purchased = Time.now

    end

  end

  class LotteryTicket

    def self.new_random

      new( rand( 25 ) + 1, rand( 25 ) + 1, rand( 25 ) + 1 )

    rescue ArgumentError

      redo

    end

  end

    class LotteryDraw

    @@tickets = {}

    def LotteryDraw.buy( customer, *tickets )

      unless @@tickets.has_key?( customer )

        @@tickets[customer] = []

      end

      @@tickets[customer] += tickets

    end

  end

    LotteryDraw.buy 'Yal-dal-rip-sip',

      LotteryTicket.new( 12, 6, 19 ),

      LotteryTicket.new( 5, 1, 3 ),

      LotteryTicket.new( 24, 6, 8 )

        class LotteryTicket

    def score( final )

      count = 0

      final.picks.each do |note|

        count +=1 if picks.include? note

      end

      count

    end

  end

    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

  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

There were about five minor problems (three missing to_s's, a
scoping issue with LotteryDraw's play & @@tickets, and a redo that
should have been a recursive call.
     I tried to change the structure as little as possible, so that you
can see what I did.

    -- Markus

class LotteryTicket
    NUMERIC_RANGE = 1..25
    attr_reader :picks, :purchased
    def initialize( *picks )
        if picks.length != 3
            raise ArgumentError, "three numbers must be picked"
          elsif picks.uniq.length != 3
            raise ArgumentError, "the three picks must be different
numbers"
          elsif picks.detect { |p| not NUMERIC_RANGE === p }
            raise ArgumentError, "the three picks must be numbers
between 1 and 25."
          end
        @picks = picks
        @purchased = Time.now
        end
    end

class LotteryTicket
    def self.new_random
        new( rand( 25 ) + 1, rand( 25 ) + 1, rand( 25 ) + 1 )
        rescue ArgumentError
            new_random
        end
    end

class LotteryDraw
    @@tickets = {}
    def LotteryDraw.buy( customer, *tickets )
        unless @@tickets.has_key?( customer )
            @@tickets[customer] =
            end
        @@tickets[customer] += tickets
        end
    end

LotteryDraw.buy 'Yal-dal-rip-sip',
LotteryTicket.new( 12, 6, 19 ),
LotteryTicket.new( 5, 1, 3 ),
LotteryTicket.new( 24, 6, 8 )

class LotteryTicket
    def score( final )
        count = 0
        final.picks.each do |note|
            count +=1 if picks.include? note
            end
        count
        end
    end

class LotteryDraw
    def self.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
    
LotteryDraw.play.each do |winner, tickets|
    puts winner + "won on " + tickets.length.to_s + " ticket(s)!"
    tickets.each do |ticket, score|
        puts "\t" + ticket.picks.join( ', ' ) + ": " + score.to_s
        end
    end

···

On Wed, 2004-10-06 at 15:43, mailinglist_abe@yahoo.com wrote:

Hey, I've been an avid reader of the Why's Poignant Guide to Ruby ever since
I discovered it (poignantguide.net), but while the material is excellent, it
is reduced in effectiveness because I'm reasonably certain that the writer
doesn't run (verbatim anyway) the code that he puts in some of the
tutorials. Namely, I'm having trouble getting a "lottery" tutorial to work,
and I'm too much of a Newb to see easily what the problem is. When I run the
code I get an error like so: "warning: class variable access from toplevel
singleton method"

My code is below, would anyone mind please skimming it and letting me know
what the errant code is? I appreciate it!

Regards, Abe

p.s. the code below is verbatim from the guide itself - I thought that
perhaps I'd mistyped something and so I copied and pasted the code into
Mondrian (the IDE I'm using)

class LotteryTicket

    NUMERIC_RANGE = 1..25

    attr_reader :picks, :purchased

    def initialize( *picks )

      if picks.length != 3

        raise ArgumentError, "three numbers must be picked"

      elsif picks.uniq.length != 3

        raise ArgumentError, "the three picks must be different numbers"

      elsif picks.detect { |p| not NUMERIC_RANGE === p }

        raise ArgumentError, "the three picks must be numbers between 1 and
25."

      end

      @picks = picks

      @purchased = Time.now

    end

  end

  class LotteryTicket

    def self.new_random

      new( rand( 25 ) + 1, rand( 25 ) + 1, rand( 25 ) + 1 )

    rescue ArgumentError

      redo

    end

  end

    class LotteryDraw

    @@tickets = {}

    def LotteryDraw.buy( customer, *tickets )

      unless @@tickets.has_key?( customer )

        @@tickets[customer] =

      end

      @@tickets[customer] += tickets

    end

  end

    LotteryDraw.buy 'Yal-dal-rip-sip',

      LotteryTicket.new( 12, 6, 19 ),

      LotteryTicket.new( 5, 1, 3 ),

      LotteryTicket.new( 24, 6, 8 )

        class LotteryTicket

    def score( final )

      count = 0

      final.picks.each do |note|

        count +=1 if picks.include? note

      end

      count

    end

  end

    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

  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

Abe, hi,

Hey, I've been an avid reader of the Why's Poignant Guide to Ruby ever since
I discovered it (poignantguide.net), but while the material is excellent, it
is reduced in effectiveness because I'm reasonably certain that the writer
doesn't run (verbatim anyway) the code that he puts in some of the
tutorials.

Many of the examples in chapter five have little problems. A few of
them I am replacing completely. Please pardon me, there's so much to
making it all cohesive. Yeah, I'm glad you poked your head out and said
so. I wasn't aware of the problems in this section.

Give the code Markus has provided (thanks markus) a try and let me know.
It'd be great if you could come join the poignant guide discussion list
so I can followup on thiis and other readers can check in and maybe
they've had the same deal.
<http://rubyforge.org/mailman/listinfo/poignant-stiffs&gt;

If this reply seems totally incoherent, sorry, I'm typing on a handheld
wee board. And I'm getting finger grease all over the place.

Ok,

_why

···

mailinglist_abe@yahoo.com (mailinglist_abe@yahoo.com) wrote: