Ruby 1.9.3和Ruby 2.0的arity的对比
为Mac OS X写了个rm时将文件放入回收站的小工具

Ruby class variable另一奇怪现象的可能的解释

bachue posted @ 2013年4月24日 18:00 in Ruby with tags variable local variable class variable instance variable ruby rails object toplevel main class , 4681 阅读

Ruby的class variable由于其奇怪的特性,一直是Ruby中包含争议的部分,大部分Rubist表示不使用class variable,最早我看到的文章是这篇写于2007年的帖子,里面的

@@avar = 1
class A
  @@avar = "hello"
end
puts @@avar  # => hello

成为了一个经典案例,至于其解释就是Ruby的class variable不属于owner类本身,而属于它的继承结构。@@avar实际定义在main所在类Object中,A继承自Object,因此也继承了@@avar这个class variable。

而昨天我又发现了另一个奇怪的特性

class A
  @@a = 1
  def f
    @@a
  end

  def f=(v)
    @@a = v
  end
end

A.new.f #=> 1
A.new.f = 2
A.new.f #=> 2

class A
  def self.f1
    @@a
  end

  class << self
    def f2
      @@a
    end
  end
end

A.f1 #=> 2
A.f2 #=> 2

# 直到这里,所有内容都可以理解
class << A
  def f3
    @@a
  end
end

A.f3 
#=> warning: class variable access from toplevel
#=> NameError: uninitialized class variable @@a in Object

这段代码的问题在于

class << A; ... ;end

class A; class << self; ... ; end; end

这两段代码本该是没有区别的,但是用后者访问的到A的class variable @@a而用前者却访问不到

当晚我把这段代码在Ruby Tuesday上提出过,也没人能回答我。回去以后仔细想想,可能觉得class variable对于gateway scope的敏感程度和其它两种变量类型local variable和instance variable不一样,在Ruby中,local variable不能穿越gateway scope存在,比如

a = 1
class A
  b = 2
  def f
    local_variables
  end
end
A.new.f #=> []

无论是a还是b,都没能进入到A的instance method f的定义中。而instance variable虽然也不能穿越gateway scope,但是等到gateway scope相同的时候却可以恢复出来

class A
  def self.f1
    @a = 1
  end

  def f2
    @a = 2
  end

  def self.f3
    @a
  end

  def f4
    @a
  end
end

A.f1
A.f3 #=> 1

a = A.new
a.f2
a.f4 #=> 2

但是class variable和它们恐怕都不一致,它是可以穿越gateway scope而存在的,比如

class A
  @@a = 1
  def f
    @@a
  end

  def f=(v)
    @@a = v
  end

  def self.f1
    @@a
  end
end

A.new.f #=> 1
A.new.f = 2
A.new.f #=> 2
A.f

可以看到,@@a在class A定义的类定义内就像全部变量一样的存在,轻松突破gateway scope,可以出现在类定义所在的每个角落。如果是这样的话,那就可以猜测了,class variable表现和其他变量类型不一致,对它而言只有class Xxxx的语句才是真正的gateway scope,其它语句统统ignore掉,包括class << Xxxxx在内。可以用以下代码证明:

class << A
  @@a = 1
end
@@a #=> 1
self.class #=> Object
self.class.class_variables #=> [:@@a]

看上去class variable定义在了A类中,但其实定义在了main所在类Object中。

王思聪 说:
2014年9月12日 17:51

博主真屌丝,写程序写的好小心孤独一生!

Patna Board Inter Qu 说:
2022年8月16日 17:46

We advise any test-takers who wish to examine their Bihar intermediate Question Paper 2023 to use the Bihar Board 11th Model Paper with Answers. Download sample test questions for the arts History The study of politics Sociology Philosophy economy, psychology, and geography Domestic Science Commerce Sample Exam Papers Accountancy Economics, Business, Entrepreneurship, and Humanities Sample Test Questions Spanish Hindi Literature and Language English Urdu Science Model Question Papers from Maithilli Chemistry Biology Physics Patna Board Inter Question Paper 2023 Mathematics Patna Board Inter Question Paper 2023, BSEB 11th Model Paper 2023 On this website, we offer tips and information on how students may prepare for exams. Important Question Paper 2023 from Patna Board. Get your Patna Board Inter 11th Class Important Question Paper 2023 by simply following the instructions.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter