那些线是什么?
我粗略的看了下代码:
Allocates space for a new object of class’s class and does not call initialize on the new instance. The returned object must be an instance of class.
allocates 不执行 initialize 方法,导致 @entity 为 空。试试这个 obj = MyStruct.malloc 目测可能可以。
#11 楼 @yedingding 我估计是,因为以前的节目都没有问题。其实问题也到不大,只是一个耳机总觉得听不清楚。
#6 楼 @yedingding 好比两个人一个在左边,一个在又边。以前都不会的。
#5 楼 @yedingding 我也不知道我表达准确不准确,也不知道大家是不是也这样。但是他们说话的声音只能一个耳机传过来。比如 terry 说话的时候 右边听得到,左边听不到,另外一个人说话的声音又换了一个耳机。
你们不会么。?
单声道的,听的我都快分裂了。
不管怎么解决这个问题,对于项目来说任意改变 module 的顺序都有大风险。
#30 楼 @zhenjunluo 和你说的 self 作用域什么的没有关系,定义方法的时候作用域和 self 也发生变化了,比如:
module M
N = 1
end
class C
include M
def bar # 这里改变了作用域,也改变了self
puts N
puts self
end
end
C.new.bar =>
1
#<C:0x8906a20>
http://ruby-china.org/topics/4777 这篇帖子可能对你有帮助。
print("1 + 1 =",1 + 1, "\n")
这样就好了。
还有,如果方法参数大于 1 个 并且用括号包住的话,中间不能带空格,这个确实是 1.8 和 1.9 的区别,但是 1.8 也是带 warning 的。
晕死,自己逗号和 引号不注意,说 ruby 坑。。。
class A
@@v = 2 # 这个类变量是A 和 A的子类以及他们的实例的类变量。
p @@v.object_id
$t = @@v
end
@@v = 1 # 同理, 这个 @@v 定义在 main 下面, 是 Object 和 Object 的子类以及他们的实例的类变量, 所以他覆盖了 上面定义的 A 的 @@v。
A.class_variable_get :@@v #=>1 原因就是上面说的。
class C < A
@@v = 3 # 这个 @@v 就是上面 @@v,这里重新定义成了 3
end
A.class_variable_get :@@v #=> 3
结论,就是你的结论是错的。没什么优先不优先的问题,只要理解了 类变量是谁的,一切就顺理成章了,虽然有些坑难理解,但不至于说 ruby 类变量实现有问题
这么严重吧。
>> class A
>> @@avar = 'hello'
>> end
=> "hello"
>> A.class_variables
=> ["@@avar"]
>> A.class_eval { puts @@avar }
=> warning: class variable access from toplevel
NameError: uninitialized class variable @@avar in Object
你说这个?
真不觉得这是什么问题。http://www.ruby-doc.org/core-2.0/Module.html#method-i-class_eval 这里说的很明白了
Evaluates the string or block in the context of mod, except that when a block is given, constant/class variable lookup is not affected.
class_eval 后面跟 block 和 string 对寻找常量和类变量是有影响的。
上面的如果换成:
A.class_eval " puts @@avar "
也就是 lz 总结的那个,就不会有问题了。
API 已经说明白的东西,难道也算问题?
@jjym 他没有先到 main 里找变量啊
#10 楼 @zputee 我以为你的意思是 ruby 类变量 实现有 bug,我看一楼这说“@@好像实现不好,不太推荐用这个。”我以为是这个意思,一细看原来是 坑多。
其次你的示例代码有些问题。比如:
class C; @@var = 1; end
def C.hi2
@@var
end
C.hi2 #err 因为此时方法的外层类是Ojbect,
self.class.class_variable_defined? :@@var #=>false, Object类无@@var类变量,所以出错。
#这时可以使用class_eval方法切换 context
C.class_eval %{
def self.hi3;@@var; end
}
C.hi3 #=>1
#-------------------------------------
class C2;@@var2 = 200;end
class D
def self.hi1 #外层D类中没有定义@@var
@@var
end
end
D.hi1 #err
class C2
def D.hi;@@var;end # 方法的外层类的类变量@@var=200
end
D.hi #=>200
前面没问题,后面 D.hi 也不是 200 啊,注释中的外层类也就是 C2 中的 @@var 在哪?本来不太明白的同学一看更糊涂了。
最后这个观点:
- 外层类的父类的 ancestors,反向查找。Ojbect 中的类变量最优先!
有点不同看法,我觉得跟 ancestors 的顺序没有什么关系,只有覆盖的关系,主要是看谁的类变量最后被赋值。
而 include 进来 Module 的类变量不会覆盖类体系的类变量,但是假如当前类体系没有类变量,那么会变成类体系的类变量。
以上是我的理解,说的有些乱,如果哪里需要例子尽管提。
hack gem 这个代价太大。
类变量到底哪里不好?