./ruby/mixin_class_methods_global_state.txt
download original
23:48 -!- Irssi: Join to #ruby-lang was synced in 1 secs
23:58 < multi_io> what I want is a mixin that provides class methods that share
some global state
module M
@@cv = 42
def self.append_features(base)
super
base.extend(ClassMethods)
end
module ClassMethods
def cm2
puts @@cv
end
end
end
class C
include M
cm2 # => should print 42, but:
# in `cm': uninitialized class variable @@cv in M::ClassMethods (NameError)
end
Day changed to 28 Feb 2005
00:01 < shyouhei> what about a cnostant of Array?
00:01 < shyouhei> CV = [42]
00:02 < shyouhei> def cv; CV[0]; end
i.e.:
module M
CV = [42]
def self.append_features(base)
super
base.extend(ClassMethods)
end
module ClassMethods
def cv
CV[0]
end
def cv=(x)
CV[0]=x
end
end
end
class C
include M
puts cv # 42
self.cv=23
puts cv # 23
end
class C2
include M
puts self.cv # 23
end
class C3
include M
end
puts C3.cv # 23
C3.class_eval "self.cv=38"
puts C3.cv # 38
puts C.cv # 38
00:03 < shyouhei> is a good old trick -- implementation of a class variable on
ruby 1.4; before Matz introduced @@cv
00:13 < multi_io> thanks
00:14 < multi_io> yep, that works
00:10 < shyouhei> an alternative [use Module.new{block} (>1.8)]
i.e.:
module M
@@cv = 42
def self.append_features(base)
super
base.extend(ClassMethods)
end
ClassMethods = Module.new do
def cv
@@cv
end
def cv=(x)
@@cv=x
end
end
end
class C
include M
puts cv # 42
self.cv=23
puts cv # 23
end
class C2
include M
puts self.cv # 23
end
class C3
include M
end
puts C3.cv # 23
C3.class_eval "self.cv=38"
puts C3.cv # 38
puts C.cv # 38
0:27 < multi_io> shyouhei: your alternative works too, but I think I don't
fully understand why...
00:27 < multi_io> albeit...
00:27 < multi_io> maybe I do
00:29 < multi_io> is it because the block is a closure and thus accesses a
different @@cv?
00:30 < shyouhei> multi_io: exactly. blocks can "see" variables outside, while
module statements cannot.
00:32 < multi_io> shyouhei: are there any other implications when using your
alternative? I.e. the ClassMethods behaving differently?
00:34 < shyouhei> No. The only difference is that @@cv (or any other variables
if you use) can be seen or not.
(he's right I think -- at least all my unit tests kept working)
00:38 < shyouhei> ,... maybe. Some parts of ruby are difficult than what human
beging can understand :-)
00:43 < multi_io> hmm.. there appears to be one glitch: when using rdoc to
generate documentation for this, the ClassMethods's methods
are documented as if they belonged to the root namespace?C
00:44 < multi_io> (this appears to be an rdoc problem...)
00:44 < multi_io> (actually I'm surprised that rdoc generated documentation for
those methods at all...)
(so I chose the 1st alternative for the time being)
back to ruby
(C) 1998-2017 Olaf Klischat <olaf.klischat@gmail.com>