ruby 中的类方法语法
我正在读的红宝石书让我有点困惑。如果我执行以下操作,我就完全理解为什么代码会抛出错误;
class Person
def show_name
puts @name
end
end
person = Person.new
person.show_name
Person.show_name #(note the capital P) this line falls over
它抛出一个错误,指出 Person 类没有名为 show_name 的方法,因为它是一个实例方法。我完全理解这一点。然后这本书抛出了这个例子;
class Class
def add_accessor(accessor_name)
self.class_eval %Q{attr_accessor :#{accessor_name}}
end
end
class Person
end
person = Person.new
Person.add_accessor :name #note the capital P
Person.add_accessor :age #capital P here too
person.name = "Mikey"
person.age = 30
puts person.name
并继续说明可以动态向类添加方法是多么酷。我不明白的是,当方法本身没有这样定义时,为什么我突然被允许将“add_accessor”方法作为类方法(带有大写的 P)调用?我认为所有类方法都必须这样声明?
class Math
def self.PI
3.141
end
end
puts Math.PI
有人能启发我吗?
the ruby book I'm reading has confused me a bit. If I do the following, I understand completely why the code throws an error;
class Person
def show_name
puts @name
end
end
person = Person.new
person.show_name
Person.show_name #(note the capital P) this line falls over
It throws an error stating that the Person class does not have a method called show_name, because it is an instance method. I understand this completely. The book then throws in this example;
class Class
def add_accessor(accessor_name)
self.class_eval %Q{attr_accessor :#{accessor_name}}
end
end
class Person
end
person = Person.new
Person.add_accessor :name #note the capital P
Person.add_accessor :age #capital P here too
person.name = "Mikey"
person.age = 30
puts person.name
and goes on to state how cool it is that you can add methods to classes dynamically. What I don't understand is why I am suddenly allowed to call the "add_accessor" method as a class method (with a capital P) when the method itself isn't defined as such? I thought all class methods had to be declared like this?
class Math
def self.PI
3.141
end
end
puts Math.PI
Is anyone able to enlighten me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Ruby 类与其他所有对象一样都是对象。您的 Person 类实际上是 Class 类的一个对象,而 Class 又继承自 Module 类。当您将一个方法作为实例方法添加到 Class 类时,您就为所有类提供了一个新方法。
如果您在 Person 中使用
def
声明了它,那么没有对象就无法调用它。要为一个类(但不是全部)添加类方法,您必须在方法名称前添加 self 或类的名称:当您将方法声明为
self.class_method
时,您将声明您的方法为类对象上的单例方法。类或模块声明中的self
指的是类对象,这就是self.
和Person.
相同的原因。在处理 Ruby 时,只要记住一切都是对象,一切都有方法。 Ruby 中也没有函数,尽管表面上与此相反。方法和对象,始终如此。
Ruby classes are objects like everything else to. Your Person class is really an object of class Class, which in turn inherits from class Module. When you add a method to class Class as an instance method, you are providing a new method for all classes.
If you had declared it with a
def
in Person, it would not be callable without an object. To add class methods for one class, but not all, you must prepend the method name with self or the name of the class:When you declare the method as
self.class_method
you are declaring your method to be a singleton method on the class object.self
in a class or module declaration refers to the class object, which is whyself.
andPerson.
are the same.When dealing with Ruby, just remember everything is an object, everything has methods. There are no functions in Ruby either, despite appearances to the contrary. Methods and objects, always.
看一下:
您已经为类
Class
的所有实例定义了一个实例方法add_accessor
,因此Person
类可以使用该方法,因为它是Class
的一个实例。我建议您查看元编程和 Ruby 对象模型。
霍普这有帮助
Look at this:
You have defined an instance method
add_accessor
for all the instances of the classClass
, soPerson
class can use that method because it is an instance ofClass
.I recommend yout to take a look at metaprogramming and Ruby Object Model.
Hoep this helps
您正在扩展
Class
类,并且您的所有类(如Person
)都是Class
的实例(是的,类是Class
类。它们是普通对象)。因此,当您调用
Person.add_accessor
时,您正在调用实例方法Class#add_accessor
。You're extending the
Class
class, and all of your classes, likePerson
, are instances ofClass
(Yes, classes are instances of theClass
class. They're ordinary objects).So when you call
Person.add_accessor
, you're calling the instance methodClass#add_accessor
.因为 Person (大写 P )是 Class 类的一个实例。
because Person (with capital P ) is an instance of the class Class.