What does this warning actually mean?

So, I'm trying my hand at metaprogramming and am finding this the result
of executing my code with -w enabled:

warning: class variable access from toplevel singleton method

(This is spammed ad infinitum anywhere I use the overridden gets, but
it's always the same message and always the same cause: gets.)

The code it's pointing to looks like this:

def override_methods(io_in)
        puts io_in
        class << io_in
                alias :old_gets :gets
                @@override_buffer=[]
                def gets separator = $/
                        raise ArgumentError, "cannot use non-standard
separator" unless separator == $/

                        unless line = @@override_buffer.shift
                                return old_gets
                        else
                                return line
                        end
                end
                def find_end
                        for a in 1..20
                                line = self.old_gets
                                if line == "__END__\n"
                                        @@override_buffer = []
                                        break
                                else
                                        @@override_buffer << line
                                end
                        end
                        self
                end
        end
        io_in
end

def find_block_begin io_in
        io_in = override_methods(io_in)
        io_in.find_end
end

To me the culprit is likely that @@override_buffer thing, but I can't
for the life of me figure out how to get around it. My modified gets
needs access to that (shared) buffer that the added find_end method
generates while peeking ahead. @override_buffer and override_buffer
don't work (the latter for reasons obvious to me, the former ... not so
obvious).

Now, the output of the code is exactly what I expect it to be, so this
isn't a show-stopper. I am, however, in the habit of making my code -w
clean if it's at all possible. How would I do it with that snippet?

···

--
Michael T. Richter <ttmrichter@gmail.com> (GoogleTalk:
ttmrichter@gmail.com)
In his errors a man is true to type. Observe the errors and you will
know the man. (孔夫子)

Michael I got no clue what you are trying to do here, but maybe the
following is hint enouh, BTW, just do not use class variables ;).
522/23 > cat test1.rb && ruby test1.rb

  class << self
    @@a=42
    def a
      @@a +=1
    end
  end
  puts a
test1.rb:3: warning: class variable access from toplevel singleton method
test1.rb:5: warning: class variable access from toplevel singleton method
test1.rb:5: warning: class variable access from toplevel singleton method
43

···

On 8/2/07, Michael T. Richter <ttmrichter@gmail.com> wrote:

---------------------------------------------

523/24 > cat test2.rb && ruby test2.rb

  class << self
    def a
      @a||=42
      @a+=1
    end
  end
  puts a

43

HTH
Robert

--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

This much I figured out for myself, Robert. :wink: The problem is that I
need to share a variable across two functions -- a buffer, to be
precise. One function fills the buffer while the other consumes from
it. The functions are to be singleton methods on an instantiated IO
object. I can't see how to make them share an instance variable without
doing funky things like calling instance_variable_set on the object to
provide it with said instance variable before adding the singletons.
Using a class variable was a desperate test after running headlong into
a brick wall trying to share them.

As it is now, I've got it working with an additional call to
instance_variable_set before defining the singletons, but it looks kind
of clunky and I was hoping there was a more elegant approach available.

···

On Thu, 2007-02-08 at 22:04 +0900, Robert Dober wrote:

Michael I got no clue what you are trying to do here, but maybe the
following is hint enouh, BTW, just do not use class variables ;).
522/23 > cat test1.rb && ruby test1.rb

  class << self
    @@a=42
    def a
      @@a +=1
    end
  end
  puts a
test1.rb:3: warning: class variable access from toplevel singleton method
test1.rb:5: warning: class variable access from toplevel singleton method
test1.rb:5: warning: class variable access from toplevel singleton method
43

---------------------------------------------

523/24 > cat test2.rb && ruby test2.rb

  class << self
    def a
      @a||=42
      @a+=1
    end
  end
  puts a

43

--
Michael T. Richter <ttmrichter@gmail.com> (GoogleTalk:
ttmrichter@gmail.com)
Our outrage at China notwithstanding, we should remember that before
1891 the copyrights of foreigners were not protected in the United
States. (Lawrence Lessig)

Michael I got no clue what you are trying to do here, but maybe thefollowing is hint enouh, BTW, just do not use class variables ;).522/23 > cat test1.rb && ruby test1.rb
  class << self @@a=42 def a @@a +=1 end end puts atest1.rb:3: warning: class variable access from toplevel singleton methodtest1.rb:5: warning: class variable access from toplevel singleton methodtest1.rb:5: warning: class variable access from toplevel singleton method43
---------------------------------------------
523/24 > cat test2.rb && ruby test2.rb
  class << self def a @a||=42 @a+=1 end end puts a

43

Michael please post in raw text format, this reads terribly and can probably
not go to the newsgroup.

This much I figured out for myself, Robert. [image: ;)]

If you did you should know exactly how to solve the problem, use class
instance variables instead of class variables. A sound advice in all cases
:slight_smile:

The problem is that I need to share a variable across *two* functions -- a

buffer, to be precise. One function fills the buffer while the other
consumes from it. The functions are to be singleton methods on an
instantiated IO object. I can't see how to make them share an instance
variable without doing funky things like calling instance_variable_set on
the object to provide it with said instance variable before adding the
singletons. Using a class variable was a desperate test after running
headlong into a brick wall trying to share them.

You see we are not talking instance variables here, actually we are, the
important thing is instance variable of what, of the class object, or in
your case singleton class object, that will perfectly do the trick.

As it is now, I've got it working with an additional call to

instance_variable_set before defining the singletons, but it looks kind of
clunky and I was hoping there was a more elegant approach available.

sure does, sure is.

Robert

···

On 8/2/07, Michael T. Richter <ttmrichter@gmail.com> wrote:

On Thu, 2007-02-08 at 22:04 +0900, Robert Dober wrote:

--

*Michael T. Richter* <ttmrichter@gmail.com> (*GoogleTalk:*
ttmrichter@gmail.com)
*Our outrage at China notwithstanding, we should remember that before 1891
the copyrights of foreigners were not protected in the United States.
(Lawrence Lessig)*

--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein