Dynamic Ruby Classes. How to fix "warning: class variable access from toplevel"

I am trying to write a program that dynamically defines ruby ​​classes based on the configuration read from a file. I know I can use Class.new for this. Here is an example program:

x = [1,2,3] Test = Class.new do @@mylist = x def foo puts @@mylist end end Test.new.foo 

When I run this, I get the following output (works with ruby ​​1.9.3p0):

  c: /utils/test.rb: 4: warning: class variable access from toplevel
 c: /utils/test.rb: 7: warning: class variable access from toplevel
 one
 2
 3 

Does anyone know what causes these warnings and how can I get rid of them?

I tried replacing the tjhat string

 @@mylist = x 

with this

 class_variable_set(:@@mylist, x) 

But when I do this, I get this error:

  c: /utils/test.rb: 7: warning: class variable access from toplevel
 c: /utils/test.rb: 7: in `foo ': uninitialized class variable @@ mylist in Object (NameError)
         from c: /utils/test.rb: 11: in `` 

Thanks in advance!

+12
oop ruby dynamic warnings
Nov 04 2018-11-11T00:
source share
3 answers

To remove this warning, you must use the class_variable_set method:

 x = [1,2,3] Test = Class.new do class_variable_set(:@@mylist, x) def foo puts @@mylist end end 
+7
Nov 04 '11 at
source share

It does not do what you think it does. Since you are not creating a class with the class keyword, your class variable is set to Object , not Test . The implications of this are quite huge, so Ruby warns you. Class variables are shared between ancestors, and objects are usually inherited from Object .

+14
May 23 '12 at 1:46 am
source share

Instead of defining your class variable "mylist" of a class when declaring a class, you can declare class level variables on it later, as shown below. Two different methods are shown. The former works only in 1.9, the latter works in both versions, but is less idiomatic.

 x = [1,2,3] Test = Class.new do def foo puts @@mylist end end # ruby 1.9.2 Test.class_variable_set(:@@mylist, x) # ruby 1.8.7 Test.class_eval { @@mylist = x } Test.new.foo 
+1
Nov 04 2018-11-21T00:
source share



All Articles