新手问题 class_eval{} 与 class_eval do..end 有什么区别吗?

whatever0914 · 2012年10月29日 · 最后由 whatever0914 回复于 2012年10月29日 · 2836 次阅读

学写例子,发现以下一个问题,请帮忙看下。

代码中通过 class_eval 来注入 getter 方法,如果写成 class_eval{code} 就无法正常执行,问题出在哪里呢?

class Module private

def readonly(*sym) puts sym return if sym.size ==0 code =""

sym.each do |m| code << "def #{m}; @#{m};end\n" end

class_eval code end

def readwrite(*sym) return if sym.size == 0 code =""

sym.each do |m| code << "def #{m};@#{m};end\n" code << "def #{m}=(c);@#{m} = c; end\n" end

#############################################

class_eval{code} 无法注入方法

############################################# class_eval do
code end end

end

class_eval code {} 哪里去了?

你把 class_eval 用错了,class_eval 有两种用法:1、接受字符串做参数 2、接受 一个 block({...} 或者 do ... end) 作为参数。

class MyClass
end
# 用法一
code = "def test; 'my test'; end"
MyClass.class_eval(code)
# 用法二
MyClass.class_eval { def test; "my_test"; end }

当然你也可以在串字符串做参数的同时给 class_eval 带一个 block 过去。 另外: { .. }do ... end 的区别是: 1、按照惯例一般 {} 用于一行代码的 block,而 do...end 用于多行代码,只是惯例,你不喜欢的话可以不遵守 2、{...} 的优先级要高于 do..end 例如:

p 3.times { 3 }      #=>   3
p 3.times do 
 3
end                  #=>   #<Enumerator: ...>

但是它们在你的例子中是没有区别的。你上面的代码

class_evel do
 code
end

同样是不能实现生成 getter 和 setter 的目的的。 建议楼主找本 ruby 的书把一些基本概念(尤其是 block)好好看看。

多谢 zzhattzzh!

是我看错了,的确 class_eval do..end 也不能实现 getter 或 setter 目的。 正在学习 ruby,看喜鹊书。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号