ruby – 从模块创建类方法
发布时间:2020-12-17 02:37:05 所属栏目:百科 来源:网络整理
导读:给出一个简单的例子: class Base @tag = nil def self.tag(v = nil) return @tag unless v @tag = v end end class A Base tag :Aendclass B Base tag :Bend class C Base; endputs "A: #{A.tag}"puts "B: #{B.tag}"puts "A: #{A.tag}"puts "C: #{C.tag}"
给出一个简单的例子:
class Base @tag = nil def self.tag(v = nil) return @tag unless v @tag = v end end class A < Base tag :A end class B < Base tag :B end class C < Base; end puts "A: #{A.tag}" puts "B: #{B.tag}" puts "A: #{A.tag}" puts "C: #{C.tag}" 它按预期工作 A: A B: B A: A C: 我想创建一个模块,该模块将扩展为提供相同的功能,但具有该类指定的所有标记信息.例如. module Tester def add_ident(v); ....; end end class Base extend Tester add_ident :tag end 我发现我可以直接使用它,所以: def add_ident(v) v = v.to_s eval "def self.#{v}(t = nil); return @#{v} unless t; @#{v} = t; end" end 但我真的不喜欢在任何语言中使用eval字符串. 有没有办法可以在不使用eval的情况下获得此功能?我已经完成了我能想到的define_method和instance_variable_get / set的每个组合,我无法让它工作. 没有Rails的Ruby 1.9. 解决方法
您希望在要扩展的类的单例类上定义动态方法.可以使用如下表达式访问类的单例类:class<<自;自我结束.要打开类的范围,可以使用class_eval.把所有这些放在一起,你可以写:
module Identification def add_identifier(identifier) (class << self; self end).class_eval do define_method(identifier) do |*args| value = args.first if value instance_variable_set("@#{identifier}",value) else instance_variable_get("@#{identifier}") end end end end end class A extend Identification add_identifier :tag end 如果您使用的是最新版本的Ruby,则可以使用Module#define_singleton_method替换此方法: module Identification def add_identifier(identifier) define_singleton_method(identifier) do |value = nil| if value instance_variable_set("@#{identifier}",value) else instance_variable_get("@#{identifier}") end end end end 我不相信你想使用self.class.send(:define_method),如另一个答案所示;这有一个意外的副作用,即将动态方法添加到self.class的所有子类中,在我的示例中,A的情况是Class. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |