作者godfat (godfat 真常)
看板Ruby
标题Re: [问题] Module观念的问题
时间Thu Feb 1 13:02:42 2007
※ 引述《yzugsr (Bird)》之铭言:
: ※ 引述《yzugsr (Bird)》之铭言:
: : 我好像没讲清楚 @@
: : 简单来说,我是希望在module A中evaluate一个字串
: : 创造出::B的物件(而非A::B) 也就是说不要在A的nesting之下
: 自己try出来了
: module A
: def self.test
: str = "class B; end"
: Object.class_eval(str)
: end
: end
: A.test
: 加了红字就会建出::B,不加就会建出A::B
: 其实我也不知其所以然....
容我推测
没写 Object. 当然是 self. 的意思
亦即以当前 scope 为基准,在 A.test 中当然是指 A
所以产生出来的 class 自然是在 A 里面了
如果你写成 Object. 的话,就变成写到 Object 这个 class 里面
所以 B 其实是 Object::B 而非 ::B
只是 global(top-level)同样是一个 Object,
所以你会觉得好像是在 global 里,但其实他是在 Object 里
也就是说其实你还可以这样写:
A.test # 产生 Object.B
B::B.new # 产生 B 的 B XD
B::B::B::B.new # 产生 B 的 B 的 B 的 B XD
class T; end
T::B::B.new # T 底下也有 B 喔…
不过经过我刚刚测试的结果,这样其实会有 warning 的
warning: toplevel constant B referenced by B::B
所以比较建议的方式是
module A
def self.test
str = "class B; end"
Kernel.class_eval(str)
end
end
A.test
这样的话,就不能做像上面那样的蠢事了
但还是每个地方都能存取到 B,(which is a constant refer to a Class)
因为 Kernel 是被 include 至 Object 里的
另外个人比较建议使用 module_eval 而不是 class_eval,
这两个基本上是完全相同的,之所以说比较建议前者是因为:
Class 也是一种(kind_of?)Module, 所以 module_eval 比较合乎
Ruby 本身的物件结构。当然这只是个人感觉,既然两者同义,
任何一个又没有被 deprecated, 所以用哪个就看个人喜好了
--
「行け!Loki!」
(rocky ロッキー)
-Gurumin ぐるみん 王子? XD
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18
1F:推 polarpolar:其实我不知道能直接写 ::B ...... Orz 02/01 15:09
2F:→ polarpolar:板主自己 m 一个吧 XDD 02/01 15:09
3F:推 godfat:应要求 XDD 02/01 19:58
4F:推 PsMonkey:咪的,那 #512 也 m 一下,虽然我看不懂 02/01 21:15
5F:→ godfat:那下一个 m #1024 XD 02/01 21:24