What does this warning actually mean?


#1

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?


#2

On 8/2/07, Michael T. Richter removed_email_address@domain.invalid 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

HTH
Robert


#3

On 8/2/07, Michael T. Richter removed_email_address@domain.invalid wrote:

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