Ruby 不修改类的全局方法
我有很多类和很多对象,我想在这些对象上应用一个方法(不同的无关类) 例如:Ruby 不修改类的全局方法,ruby,Ruby,我有很多类和很多对象,我想在这些对象上应用一个方法(不同的无关类) 例如: pig = animal.new pig.name = "lulu" human = person.new human.firstname = "John" #There isn't method called "name". def seeName puts self.name if (self.name?) puts self.firstname if (self.firstname?) end pig.s
pig = animal.new
pig.name = "lulu"
human = person.new
human.firstname = "John" #There isn't method called "name".
def seeName
puts self.name if (self.name?)
puts self.firstname if (self.firstname?)
end
pig.seeName
human.seeName
这只是一个例子。。。
我认为这是不可能的,但我正在寻找一种不修改任何现有类的方法
谢谢。您应该能够做到:
def see_name(object)
return object.name if object.respond_to? :name
object.firstname if object.respond_to :firstname
end
see_name(pig) #=> "lulu"
see_name(human) #=> "John"
然而,在OOP中,这不是一种正确的方法。每当你遇到这样的问题,就意味着你的对象设计走错了方向,需要重新审视。你应该能够做到:
def see_name(object)
return object.name if object.respond_to? :name
object.firstname if object.respond_to :firstname
end
see_name(pig) #=> "lulu"
see_name(human) #=> "John"
然而,在OOP中,这不是一种正确的方法。每次遇到这样的问题,都意味着您的对象设计走错了方向,需要重新检查。您可以在
模块中定义方法,然后在运行时将其包含到所需的类中
pig = Animal.new
pig.name = "lulu"
human = Person.new
human.firstname = "John"
module SeeName
def see_name
puts self.name if (self.name?)
puts self.firstname if (self.firstname?)
end
end
Person.class_eval { include SeeName }
Animal.class_eval { include SeeName }
pig.see_name # => "lulu"
human.see_name # => "John"
(当然,前提是人和动物都支持name
,name?
,firstname
和firstname?
)您可以在模块中定义方法,然后在运行时将其包含到所需的类中
pig = Animal.new
pig.name = "lulu"
human = Person.new
human.firstname = "John"
module SeeName
def see_name
puts self.name if (self.name?)
puts self.firstname if (self.firstname?)
end
end
Person.class_eval { include SeeName }
Animal.class_eval { include SeeName }
pig.see_name # => "lulu"
human.see_name # => "John"
(当然,前提是人和动物都支持name
,name?
,firstname
和firstname?
)一位同事告诉我还有另一种方法:
class Object
def seeName
puts self.name if (self.name?)
puts self.firstname if (self.firstname?)
end
end
pig.seeName
human.seeName
到目前为止,它工作得很好。一位同事告诉我还有另一种方法:
class Object
def seeName
puts self.name if (self.name?)
puts self.firstname if (self.firstname?)
end
end
pig.seeName
human.seeName
到目前为止,它工作得很好。是在许多不同的类中定义的name?
和firstname?
吗?在考虑方法之前需要知道请参见_name
。name?
和firstname?
是在许多不同的类中定义的吗?在考虑方法之前需要知道。请参见_name
。是的,我是在我的帖子之后才想到的!谢谢:)是的,我刚发帖就想到了!谢谢:)我不认为把对象
类更改为特定于应用程序的类是明智的-这太破坏性了-现在你已经定义了'123“。seeName
以及…@Uri Agassi:哦,是的,我不这么认为,但是我永远不会对不支持这个的对象使用seeName方法。我试试你的解决办法!仅仅因为你不会,并不意味着一些粗心大意的维护人员不会。我不认为将对象
类更改为特定于应用程序的类是明智的-它太具破坏性了-现在你已经定义了'123'。请参见name
。@Uri Agassi:哦,是的,我不这么认为,但我永远不会对不支持此功能的对象使用seeName方法。我试试你的解决办法!仅仅因为你不会,并不意味着一些粗心的维护人员不会。谢谢!是否存在将class_eval
应用于加载文件中的每个类的解决方案?它们是否都在同一名称空间(模块)下?根本不存在。但是可以将load('classes_types.rb')
包含到一个模块中。我想您可以跳过一些步骤来找出在某个文件中声明了哪些类,但我认为最简单的方法是在其他地方维护该列表,然后执行类似[Person,Animal,…]的操作。每个{c | c.class_eval{include SeeName}
谢谢!是否存在将class_eval
应用于加载文件中的每个类的解决方案?它们是否都在同一名称空间(模块)下?根本不存在。但是可以将load('classes_types.rb')
包含到一个模块中。我想您可以跳过一些步骤来找出在某个文件中声明了哪些类,但我认为最简单的方法是在其他地方维护该列表,然后执行类似[Person,Animal,…]的操作。每个{c | c.class_eval{include SeeName}