From: "jeremyevans0 (Jeremy Evans)" Date: 2022-07-19T19:35:21+00:00 Subject: [ruby-core:109250] [Ruby master Bug#18927] Can't access class variable directly with class inheritance Issue #18927 has been updated by jeremyevans0 (Jeremy Evans). Class variable lookup is different from instance variable and constant lookup, but it is more similar to constant lookup. It's based on the namespace/cref containing the access, not the receiver of the method containing the access (see `vm_getclassvariable` in `vm_insnhelper.c`). Here's a modified example that works: ```ruby class Parent end class Child < Parent def Parent.class_var puts @@class_var end end class Child < Parent @@class_var = "class_var" end Child.class_var ``` The reason this works is that the `@@class_var` access is now in the `Child` namespace instead of the `Parent` namespace. I don't think this is a bug, and based on previous issues, I believe @matz is no longer considering changes to class variable semantics. It's best to avoid using class variables completely in Ruby. ---------------------------------------- Bug #18927: Can't access class variable directly with class inheritance https://bugs.ruby-lang.org/issues/18927#change-98383 * Author: jemmai (Jemma Issroff) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- If a child class inherits from a parent class, and the child class sets a class variable, the parent class can't access the class variable literal: ``` class Parent def self.class_var puts @@class_var end end class Child < Parent @@class_var = "class_var" end Child.class_var # => test.rb:3:in `class_var': uninitialized class variable @@class_var in Parent (NameError) ``` Confusingly, if we use `class_variable_get` (method lookup) to access `@@class_var`, we can access it as expected. We can alter the snippet from above to see this behavior: ``` class Parent def self.class_var puts class_variable_get(:@@class_var) puts @@class_var end end class Child < Parent @@class_var = "class_var" end Child.class_var # => "class_var" # => test.rb:4:in `class_var': uninitialized class variable @@class_var in Parent (NameError) ``` ## Is this desired behavior? `self` is the subclass so it seems like the class variable should be looked up on the receiver. Why is the method lookup resolution different than the literal? Should it be different? -- https://bugs.ruby-lang.org/ Unsubscribe: