Issue #14541 has been updated by duerst (Martin D=FCrst).


jeremyevans0 (Jeremy Evans) wrote in #note-18:
 =

>but are we OK jumping directly from verbose-mode warning in 2.7 to Runtime=
Error in 3.0, without issuing a non-verbose warning?

I think that's a bad idea, virtually in every case. Let's always do this st=
ep by step, i.e. issue a warning in all cases (even non-verbose).


----------------------------------------
Bug #14541: Class variables have broken semantics, let's fix them
https://bugs.ruby-lang.org/issues/14541#change-86085

* Author: Eregon (Benoit Daloze)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* ruby -v: ruby 2.6.0dev (2018-01-29 trunk 62091) [x86_64-linux]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
Class variables have the weird semantics of being tied to the class hierarc=
hy and being inherited between classes.
I think this is counter-intuitive, dangerous and basically nobody expects t=
his behavior.

To illustrate that, we can break the tmpdir stdlib by defining a top-level =
class variable:

    $ ruby -rtmpdir -e '$SAFE=3D1; @@systmpdir=3D42; p Dir.mktmpdir {}'
    -e:1: warning: class variable access from toplevel
    Traceback (most recent call last):
    	3: from -e:1:in `<main>'
    	2: from /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/tmpdir.rb:86:in =
`mktmpdir'
    	1: from /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/tmpdir.rb:125:in=
 `create'
    /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/tmpdir.rb:125:in `join': =
no implicit conversion of Integer into String (TypeError)

Or even simpler in RubyGems:

    $ ruby -e '@@all=3D42; p Gem.ruby_version'
    -e:1: warning: class variable access from toplevel
    Traceback (most recent call last):
    	3: from -e:1:in `<main>'
    	2: from /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/rubygems.rb:984:=
in `ruby_version'
    	1: from /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/rubygems/version=
.rb:199:in `new'
    /home/eregon/prefix/ruby-trunk/lib/ruby/2.6.0/rubygems/version.rb:199:i=
n `[]': no implicit conversion of String into Integer (TypeError)

So defining a class variable on Object removes class variables in all class=
es inheriting from Object.
Maybe @@systmpdir is not so prone to conflict, but how about @@identifier, =
@@context, @@locales, @@sequence, @@all, etc which are class variables of t=
he standard library?

Moreover, class variables are extremely complex to implement correctly and =
very difficult to optimize due to the complex semantics.
In fact, none of JRuby, TruffleRuby, Rubinius and MRuby implement the "sett=
ing a class var on Object removes class vars in subclasses".
It seems all implementations but MRI print :foo twice here (instead of :foo=
 :toplevel for MRI):

~~~ ruby
class Foo
  @@cvar =3D :foo
  def self.read
    @@cvar
  end
end

p Foo.read
@@cvar =3D :toplevel
p Foo.read
~~~


Is there any library actually taking advantage that class variables are inh=
erited between classes? I would guess not or very few.
Therefore, I propose to give class variable intuitive semantics: no inherit=
ance, they behave just like variables of that specific class, much like cla=
ss-level instance variables (but separate for compatibility).

Another option is to remove them completely, but that's likely too hard for=
 compatibility.

Thoughts?



-- =

https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=3Dunsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>