Gui*_*nal 6 ruby metaprogramming
我在Ruby中使用元编程开玩笑,我做了这段代码:
class Class
def ===(other)
other.kind_of?(self)
end
end
class FakeClass
def initialize(object)
methods.each {|m| eval "undef #{m}" if m.to_sym != :methods }
define = proc do |m|
eval(<<-END)
def #{m}(*a, &b)
@object.#{m}(*a, &b)
rescue Object
raise $!.class, $!.message.gsub("FakeClass", @object.class.to_s),
$!.backtrace-[$!.backtrace[-caller.size-1]]
end
END
end
object.methods.each {|m| define[m] }
def method_missing(name, *a, &b)
if @object.methods.include?(name.to_s)
define[name]
eval "@object.#{name}(*a, &b)"
elsif @object.methods.include?("method_missing")
eval "@object.#{name}(*a, &b)"
else
super
end
rescue Object
raise $!.class, $!.message.gsub("FakeClass", @object.class.to_s),
$!.backtrace-[$!.backtrace[-caller.size-1]]
end
@object = object
end
end
Run Code Online (Sandbox Code Playgroud)
这会创建一个模仿对象的假类.看:
a = FakeClass.new(1) # => 1
a.class # => Fixnum
a.methods # => Return all Fixnum methods
a + 1 # => 2 (is not a FakeClass)
Fixnum === a # => true
a.something # => NoMethodError:
# undefined method `something' for 1:Fixnum
class Fixnum
def foo
true
end
end
a.foo # => true
Run Code Online (Sandbox Code Playgroud)
问题是,现在我不知道如何知道对象是真的还是假的.换句话说,如果#class返回对象的真实类.存在一些纯粹的红宝石方式来区分?
想想在我不知道FakeClass存在的情况下,或者我不知道FakeClass的名称是什么.这意味着我无法编辑FakeClass来添加类似的方法#is_fake?.
PS:我知道a.instance_eval {self}返回对象(不是假的).但检查是否a是假的无济于事.
这是另一个答案:
a = FakeClass.new(1)
b = 1
da = Marshal.dump(a)
db = Marshal.dump(b)
puts da == db #=> false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
442 次 |
| 最近记录: |