- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我卡住了。我正在尝试动态定义一个类方法,但我无法全神贯注于 ruby 元类模型。考虑以下类:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
end
Example.class_instance.class # => Class
Example.meta.class # => Class
Example.class_instance == Example # => true
Example.class_instance == Example.meta # => false
显然,这两种方法都返回一个 Class 实例。但是这两个实例不一样。他们也有不同的祖先:
Example.meta.ancestors # => [Class, Module, Object, Kernel]
Example.class_instance.ancestors # => [Example, Object, Kernel]
区分元类和类实例有什么意义?
我想通了,我可以发送 :define_method
到元类来动态定义一个方法,但是如果我尝试将它发送到类实例,它将无法工作。至少我可以解决我的问题,但我仍然想了解为什么它会这样工作。
2010 年 3 月 15 日 13:40 更新
下列假设是否正确。
我觉得这对我来说开始有意义了。如果类方法中的 self 指向本征类,那肯定会限制您的可能性。如果是这样,就不可能从类方法内部定义实例方法。对吗?
最佳答案
当您使用 instance_eval
时,动态定义单例方法很简单:
Example.instance_eval{ def square(n); n*n; end }
Example.square(2) #=> 4
# you can pass instance_eval a string as well.
Example.instance_eval "def multiply(x,y); x*y; end"
Example.multiply(3,9) #=> 27
至于上面的区别,你混淆了两件事:
您定义的元类,在 Ruby 社区中称为 singelton class 或 eigen class。该单例类是您可以向其添加类(单例)方法的类。
至于你试图使用class_instance
方法定义的类实例,只不过是类本身,为了证明这一点,只需尝试向类添加实例方法Example
并通过检查该方法的存在来检查您定义的 class_instance
方法是否返回类 Example
本身:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
def hey; puts hey; end
end
Example.class_instance.instance_methods(false) #=> ['hey']
总而言之,当您想添加类方法时,只需将它们添加到该元类中即可。至于class_instance
方法没用,去掉就好了。
无论如何,我建议您阅读 this post掌握 Ruby 反射系统的一些概念。
更新
我建议您阅读这篇精彩的文章:Fun with Ruby's instance_eval and class_eval ,不幸的是,class_eval
和 instance_eval
令人困惑,因为它们在某种程度上违背了它们的命名!
Use ClassName.instance_eval to define class methods.
Use ClassName.class_eval to define instance methods.
现在回答你的假设:
If I have an instance method which calls self.instance_eval and defines a method, it will only affect the particular instance of that class.
是的:
class Foo
def assumption1()
self.instance_eval("def test_assumption_1; puts 'works'; end")
end
end
f1 = Foo.new
f1.assumption1
f1.methods(false) #=> ["test_assumption_1"]
f2 = Foo.new.methods(false) #=> []
If I have an instance method which calls self.class.instance_eval (which would be the same as calling class_eval) and defines a method it will affect all instances of that particular class resulting in a new instance method.
没有 instance_eval
在该上下文中将在类本身上定义单例方法(不是实例方法):
class Foo
def assumption2()
self.class.instance_eval("def test_assumption_2; puts 'works'; end")
end
end
f3 = Foo.new
f3.assumption2
f3.methods(false) #=> []
Foo.singleton_methods(false) #=> ["test_assumption_2"]
为此,请将 instance_eval
替换为上面的 class_eval
。
If I have a class method which calls instance_eval and defines a method it will result in a new instance method for all instances.
没有:
class Foo
instance_eval do
def assumption3()
puts 'works'
end
end
end
Foo.instance_methods(false) #=> []
Foo.singleton_methods(false) #=> ["assumption_3"]
这将生成单例方法,而不是实例方法。为此,请将 instance_eval
替换为上面的 class_eval
。
If I have a class method which calls instance_eval on the meta/eigen class and defines a method it will result in a class method.
嗯,不,那会做出如此复杂的东西,因为它将向单例类添加单例方法,我认为这不会有任何实际用途。
关于Ruby 元类疯狂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2446428/
在 MySQL 8.0.21 上,我有一个空表 ( Tbl ),只有一列: num , 类型 float . 我插入一行,值为 0.1 : INSERT INTO Tbl(num) VALUES(0.
我一直在阅读 Swing 教程“如何使用表”,尽管它对 JTable 新手来说提供了很多信息,但我在尝试转向时立即遇到了障碍示例并自行解决。 因此,如果您希望您的 Swing 应用程序拥有漂亮的自定义
首先,请原谅,因为我对这个有点陌生,所以我的代码看起来不太漂亮......但下面的一切都有效,## 这不是一个寻求非工作代码帮助的线程##. 现在那已经不碍事了……事情是这样的:我已经为 FF 制作了
我已将 1-1 这段代码从 C++/OpenGL 移植到 C# SharpGL: float[] cameraAngle = { 0, 0, 0 }; float[] cameraPo
背景: 我在一台旧笔记本电脑上运行。我总共只有 512Mo 可用 128Mo ram。没钱买更多的 ram。 我使用 mmap 来帮助我规避这个问题,而且效果很好。C代码。Debian 64 位。 问
这是一个奇怪的。 重命名类后,我的一个表单开始在设计器中出现错误,拒绝打开。有趣的是,当我运行该程序时,该表单运行良好。 我开始恢复我的更改以推断问题所在。我现在已经完全恢复到上次提交 - 我知道表单
我有一个项目列表,上面有不同的事件处理程序。 ... Item ... Add to list A Add to list B
我有一个静态 View ,它是一个设置 View 。它有 3 个部分 section 1 has 3 rows section 2 has 1 row section 3 has 1 row 我在每一
我大概花了一个月的时间在互联网上研究这个问题,但还没有找到答案。我的代码执行以下操作(所有 Javascript)。 假设我在 mydomain.com 上有一个 test.html 首先在 head
谁能解释一下 prototype.init 函数在 JavaScript 中的意义以及它在对象实例化过程中何时被调用? 为什么要用空函数覆盖它? 我正在阅读 JavaScript for Web 这本
我喜欢 MVVM。我不喜欢它,但喜欢它。其中大部分是有道理的。但是,我一直在阅读鼓励您编写大量代码的文章,这样您就可以编写 XAML 而不必在代码隐藏中编写任何代码。 我举个例子。 最近我想将我的 V
我遇到了一个问题,我确信许多新/初级 Web 开发人员都面临着这个问题。在陈述问题之前,最好先列出导致我出现“问题”的事件。 第 1 步 - 前端:我遵循的教程允许我使用 vue-cli 创建一个 V
所以,我做了很多搜索和摆弄,但找不到解决方案。也许我的情况很独特——或者更有可能我只是不知道我到底在做什么。我比刚开始时更接近了,所以这令人振奋。不管怎样 - 我们来了智囊团 - 非常感谢任何帮助。
iTunes connect 一直拒绝我的二进制文件进行应用程序更新,这让我发疯。通常我可以弄清楚,但我已经尝试了我能想到的一切。也许有人可以伸出援助之手:) 我得到的错误是: The binary
嗯,George Boole 的骨架一定在它的坟墓里感到有些疼痛,因为我的 bool 人刚刚变得疯狂并开始举办派对。我真的认为他们想反抗我。 现在更严重了:可能我在 $watch 方法中遗漏了一些东西
我有一个ul、链表元素和无链接的li。 Home Test1 second_level
为此搜索了答案,但找不到任何内容。我能找到的最接近的是 difftime returning 0 when there is clearly a difference其中有一个很好的解释,与如何将参数
Closed. This question is opinion-based。它当前不接受答案。
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
所以...我的问题有点奇怪。我有一个简单的 UIToolbar 被添加到在 viewDidLoad 时间调用的 navigationController 的 View 层次结构中。听起来很简单,对吧?
我是一名优秀的程序员,十分优秀!