Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中,向实例添加方法的用例是什么;什么是单身班?_Ruby_Methods_Singleton_Instance_Metaclass - Fatal编程技术网

在Ruby中,向实例添加方法的用例是什么;什么是单身班?

在Ruby中,向实例添加方法的用例是什么;什么是单身班?,ruby,methods,singleton,instance,metaclass,Ruby,Methods,Singleton,Instance,Metaclass,多亏了其他一些帖子和阅读,我理解了单例/元类。我明白我们为什么要在课堂上使用它们。但我仍然不明白为什么我们要在实例对象上使用它们。我还没有在实践中看到这一点 我指的是这样的东西: class Vehicle def odometer_reading # some code end end my_car = Vehicle.new def my_car.open_door # some code end 乍一看,这似乎是个坏主意,因为它会导致理解代码和

多亏了其他一些帖子和阅读,我理解了单例/元类。我明白我们为什么要在课堂上使用它们。但我仍然不明白为什么我们要在实例对象上使用它们。我还没有在实践中看到这一点

我指的是这样的东西:

class Vehicle
    def odometer_reading
        # some code
    end
end

my_car = Vehicle.new

def my_car.open_door
    # some code
end
乍一看,这似乎是个坏主意,因为它会导致理解代码和调试方面的困难


我们为什么要这样做?这是一个好主意的例子有哪些

您不会使用
def
添加它们,这是一种相当严格的方法,而是使用类似
define\u method
extend
的方法

虽然这不是你日常所做的事情,但它确实意味着你可以做一些不寻常的事情。Rails中的ActiveRecord以数组的形式生成结果,并添加其他方法来执行其他操作


对象关系映射器可能是您希望执行此操作的情况。有时,根据获取记录的方式,可用的方法会有很大的不同。能够动态添加这些对象意味着每个获取的对象都可以完全定制,即使它们具有相同的类和通用方法。

有一个示例将其用于测试目的:创建模拟对象和双对象、存根方法。调试就在附近:为您怀疑有误的特定对象重新定义日志记录方法,以便在调试会话期间将日志信息直接打印到控制台(或打印更多信息)

另一个例子是处理特殊情况,而不是继承,你可以这样做。从一个经典示例开始,如果您使用两种类型的
员工
s,例如
工程师
s和
销售人员
s,这两种类型的薪酬计算规则不同,您可以将通用逻辑放入
员工
类中,然后从中继承其他两个类,并在那里实现它们自己的
calculate\u salary
方法。现在,如果有一个离群者——一个与你达成不同薪酬方案的明星销售员,一个拥有非常特殊方案的CEO,等等——而不是为这个特殊员工创建一个完整的子类,你可以为代表这个员工的特定对象定义这个方法


第三个示例涉及对象生命周期和性能考虑。而不是在某些处理方法中具有各种状态的长
情况。例如,对于在后台透明缓存整个文件的文件读取类(我知道对于现实生活中的方法来说过于简单,但只是作为一个模型),当文件未完全读取时,所有读取请求都应检查请求的数据是否已经在缓存中或应该从磁盘读取。一旦文件被完全读取,它们总是从缓存中取出。当文件被完全读取到缓存中时,您可以简单地在对象级别重新定义
read
方法,而不是使用
if
case
,如果存在更多状态)来处理此问题。对于这个简单的示例,它不会带来任何可观的性能好处(如果有任何好处的话),但是对于更复杂的情况,它可能是值得的。

另一个示例:您有一个哈希数组,并且希望每个哈希都有一个方法调用getter和setter。比如:

user = HashOnSteroids.new(name: 'John')
user[:name] # => 'John'
user[:name] = 'Joe'
user.name # => 'Joe'
user.name = 'John'
user.set(name: 'Jim', age: 5)
这意味着您不能在类中编写标准方法定义,因为每个哈希将具有不同的键集(方法名称)。这意味着您必须求助于定义单例方法,以便每个对象都有自己的方法集(而不是一组共享方法)


警告:在此用例中使用单例方法效率极低。一个偷偷摸摸的
方法\u missing
速度更快,占用的内存更少,因为它不需要分配十亿个proc对象。

感谢具体的例子。如果我们这样做,编程社区认为这是一个好的实践,更不用说Ruby社区了?正如你所知道的,我很难相信这是一个好主意。是的,对我来说,这似乎是一个很好的做法——非常像红宝石。在一些(非常快速的)谷歌搜索之后,有几个链接:-他们认为这很好(不管怎么说,在后台用于类方法)。本文()引用了“雄辩的Ruby”一书中提出的这种方法。现在,我手边没有这本书,但这本书几乎是经典的(对我来说,这是肯定的),作者说这本书很好,是正确的“Ruby方式”的一个例子,我明白了。当你说“做一些不寻常的事情”时,我就是从这里来的。为什么我们要做不寻常的事情?我想在非常特定的情况下,这样做相对安全,这很好。下面是一个使用元编程响应文档结构的示例。OpenStruct看起来很像Javascript。我知道,但它占用的内存(MRI)大约是Javascript的5倍,而且似乎不支持大容量设置。推出我们自己的解决方案其实很简单,也很有趣。