gpt4 book ai didi

通过点调用的 Ruby 函数

转载 作者:太空宇宙 更新时间:2023-11-03 17:31:52 26 4
gpt4 key购买 nike

我想调用一个名为 my_format_number 的函数,例如:

num = 5.5
formated_num = num.my_format_number

我如何在 Ruby 中做到这一点?这些类型的函数的名称是什么?

最佳答案

what is the name of these types of functions?

在面向对象编程(独立于编程语言)中,绑定(bind)到对象(通常通过对象的类)的函数称为“方法”。 Some Ruby documentation calls all functions 'methods' , 尽管。为了区别起见,我将仅使用“方法”来表示绑定(bind)函数,并继续将函数统称为“函数”。

未绑定(bind)到对象的函数通常称为“自由函数”。

绑定(bind)方法的对象称为方法的“接收者”。

How can I do that in Ruby?

在 Ruby 中,方法始终是实例方法:它们在类上定义,但作用于类的实例。 (即,接收者必须是实例。)除了 C/C++ 或 Java 之外,Ruby 中的所有值都是对象(类的实例),因此每个值都有一个类。

类?什么课?

类是值/对象/实例的类型。它(在某种程度上)决定了值的语义,以及该值可用的方法。

5.5 的类是什么?让我们找出答案:

(5.5).class()
# => Float

(较短的 5.5.class 也可以,但有点难以理解。)

Float 是 Ruby 的内置 float 类。

修改Float

Ruby 中的类定义可以拆分和分布。除了已经生效的 block 之外,每个 block 在被解释后都会生效,这意味着您可以在运行时修改类。这被称为“猴子修补”或“重新开课”。

让我们重新打开Float 类并添加my_format_number 方法。我决定它应该返回一个字符串:

class Float
def my_format_number
return "The number is #{self} and #{self} is the number."
end
end

(可以跳过字符串前面的 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.

我们甚至不需要变量,可以直接在值文字上调用方法:

puts 7.8.my_format_number
# The number is 7.8 and 7.8 is the number.

虽然它不适用于所有数字:

100.my_format_number
# NoMethodError: undefined method `my_format_number' for 100:Fixnum
# from (irb):15
# from :0

那是因为我们定义了 Float100 的数量(正如错误消息告诉我们的那样)不是 Float 而是 Fixnum(一种特殊的 Integer)。

一次修改多个相关类

当然,您现在也可以定义Fixnum 的函数。但是有些数字既不是 Fixnum 也不是 Float。因此,将功能放在某个中心位置是有意义的。

我们可以猴子修补 Ruby 的主类,Object。但这将允许

"foobar".my_format_number

返回 “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

superclass 方法只给了我们一个直接的祖先。使用 Ruby 模块,多重继承是可能的,因此我们可以获得更多的结果,如下所示:

Fixnum.ancestors
# => [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]

让我们看看重叠是什么

Float.ancestors()
# => [Float, Precision, Numeric, Comparable, Object, Kernel]

Comparable 可能比数字更笼统,而 Precision 可能过于具体甚至有点不相关。 (它可能是一个模块。)让我们修改 Numeric,这样(从它的名字猜测)听起来像是正确的抽象级别。事实上,the documentation叫它

The top-level number class.

因此,与之前非常相似,

class Numeric
def my_format_number
return "The number is #{self} and #{self} is the number."
end
end

现在

100.my_format_number
# => "The number is 100 and 100 is the number."

如果您想知道我们在第二次猴子修补中添加了该方法的所有类,请查看Look up all descendants of a class in Ruby。 .

关于通过点调用的 Ruby 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32921955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com