我想调用一个名为my_format_number如下的函数:
num = 5.5
formated_num = num.my_format_number
Run Code Online (Sandbox Code Playgroud)
我怎样才能在 Ruby 中做到这一点?这些类型的函数的名称是什么?
这些类型的函数的名称是什么?
在面向对象编程(独立于编程语言)中,绑定到对象(通常通过对象的类)的函数称为“方法”。不过,一些 Ruby 文档将所有函数都称为“方法”。为区分起见,我将使用“方法”仅表示绑定函数,并继续将一般的函数称为“函数”。
未绑定到对象的函数通常称为“自由函数”。
方法绑定到的对象称为方法的“接收者”。
我怎样才能在 Ruby 中做到这一点?
在 Ruby 中,方法总是实例方法:它们在类上定义,但作用于类的实例。(即,接收者必须是一个实例。)除了在 C/C++ 或 Java 中,Ruby 中的所有值都是对象(类的实例),因此每个值都有一个类。
类是值/对象/实例的类型。它确定(在某种程度上)值的语义,以及对该值可用的方法。
什么是班级5.5?让我们来了解一下:
(5.5).class()
# => Float
Run Code Online (Sandbox Code Playgroud)
(较短的5.5.class也可以,但有点难以理解。)
Float 是 Ruby 的内置浮点数类。
Float类Ruby 中的类定义可以拆分和分发。每个块在解释后都会生效,除了已经生效的块之外,这意味着您可以在运行时修改类。这被称为“猴子修补”或“重新开设课程”。
让我们重新打开Float类并添加my_format_number方法。我决定它应该返回一个字符串:
class Float
def my_format_number
return "The number is #{self} and #{self} is the number."
end
end
Run Code Online (Sandbox Code Playgroud)
(return字符串前面的可以被跳过,因为 Ruby 函数隐式返回它们计算的最后一个表达式。)
现在您可以对所有Float值调用新方法:
num = 5.5
formatted_num = num.my_format_number()
puts(formatted_num)
# The number is 5.5 and 5.5 is the number.
Run Code Online (Sandbox Code Playgroud)
我们甚至不需要变量,可以直接在值文字上调用该方法:
puts 7.8.my_format_number
# The number is 7.8 and 7.8 is the number.
Run Code Online (Sandbox Code Playgroud)
但是,它不适用于所有数字:
100.my_format_number
# NoMethodError: undefined method `my_format_number' for 100:Fixnum
# from (irb):15
# from :0
Run Code Online (Sandbox Code Playgroud)
那是因为我们定义了Floatand的数量100(正如错误消息告诉我们的那样)不是 aFloat而是 a Fixnum(一种特殊的Integer)。
您现在当然也可以定义Fixnum. 但是有些数字既不是Fixnums 也不Float是 s。因此,在某个中心位置拥有该功能是有意义的。
我们可以修补 Ruby 的大师班,Object. 但这将允许
"foobar".my_format_number
Run Code Online (Sandbox Code Playgroud)
return "The number is foobar and foobar is the number.",这是没有意义的,因为foobar它不是数字。我只想要我们的方法来格式化数字。
让我们看看类的Fixnum结构:
Fixnum.superclass()
# => Integer
Fixnum.superclass().superclass() # equivalent to `Integer.superclass`
# => Numeric
Fixnum.superclass().superclass().superclass() # equivalent to `Numeric.superclass`
# => Object
Run Code Online (Sandbox Code Playgroud)
该superclass方法只为我们提供了一个直接祖先。使用 Ruby 模块,多重继承是可能的,因此我们可以得到更多这样的结果:
Fixnum.ancestors
# => [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
Run Code Online (Sandbox Code Playgroud)
让我们看看重叠是什么
Float.ancestors()
# => [Float, Precision, Numeric, Comparable, Object, Kernel]
Run Code Online (Sandbox Code Playgroud)
Comparable可能比数字更笼统,而Precision可能过于具体甚至有些不相关。(它可能是一个模块。)让我们Numeric这样修改,这(从它的名字猜测)听起来像是正确的抽象级别。事实上,文档称它为
顶级数字类。
因此,与之前非常相似,
class Numeric
def my_format_number
return "The number is #{self} and #{self} is the number."
end
end
Run Code Online (Sandbox Code Playgroud)
现在
100.my_format_number
# => "The number is 100 and 100 is the number."
Run Code Online (Sandbox Code Playgroud)
如果您想知道我们在第二次猴子补丁中添加了该方法的所有类,请查看在 Ruby中查找类的所有后代。
| 归档时间: |
|
| 查看次数: |
1147 次 |
| 最近记录: |