非常教程

Ruby 2.4参考手册

语言 | 3Language

Calling Methods

调用方法会向对象发送消息,以便它可以执行一些工作。

在 ruby 中,你发送一条消息给像这样的对象:

my_method()

请注意,括号是可选的:

my_method

除了使用括号和省略括号之间的区别之外,本文档在存在参数时使用括号以避免混淆。

本节仅介绍调用方法。另请参阅定义方法的语法文档。

接收器

self是默认的接收器。如果您没有指定self将使用任何接收器。要指定接收器使用.

my_object.my_method

这发送my_method消息my_object。任何对象都可以是接收者,但取决于方法的可见性,发送消息可能会引发 NoMethodError。

你可以&.用来指定一个接收者,然后my_method不被调用,结果是nil接收者时nil。在这种情况下,参数my_method不会被评估。

您也可以::用来指定一个接收器,但由于可能与::名称空间混淆,所以很少使用。

参数

发送消息时有三种类型的参数,位置参数,关键字(或命名)参数和块参数。发送的每条消息都可以使用一个,两个或所有类型的参数,但参数必须按此顺序提供。

Ruby 中的所有参数都是通过引用传递的,并不会被懒惰地评估。

每个参数由一个,fen分离:

my_method(1, '2', :three)

参数可以是表达式,哈希参数:

'key' => value

或关键字参数:

key: value

散列和关键字参数必须是连续的,并且必须出现在所有位置参数之后,但可能是混合的:

my_method('a' => 1, b: 2, 'c' => 3)

位置参数

消息的位置参数遵循方法名称:

my_method(argument1, argument2)

在许多情况下,发送消息时不需要括号:

my_method argument1, argument2

但是,括号是避免含糊不清的必要条件。这将引发一个 SyntaxError,因为 ruby 不知道应该发送哪个方法参数3:

method_one argument1, method_two argument2, argument3

如果方法定义有一个*argument额外的位置参数,则将argument在方法中将其指定为一个 Array。

如果方法定义不包含关键字参数,则将关键字或散列类型参数指定为最后一个参数的单个散列值:

def my_method(options)
  p options
end

my_method('a' => 1, b: 2) # prints: {'a'=>1, :b=>2}

如果提供了太多的位置参数,则会引发一个 ArgumentError。

默认位置参数

当方法定义默认参数时,您不需要为该方法提供所有参数。Ruby 将按顺序填写缺失的参数。

首先,我们将介绍右侧显示默认参数的简单情况。考虑这种方法:

def my_method(a, b, c = 3, d = 4)
  p [a, b, c, d]
end

这里cd具有红宝石将适用于你的默认值。如果您仅向此方法发送两个参数:

my_method(1, 2)

你会看到 ruby 打印[1, 2, 3, 4]

如果您发送三个参数:

my_method(1, 2, 5)

你会看到 ruby 打印 [1, 2, 5, 4]

Ruby 从左到右填充缺失的参数。

Ruby 允许默认值出现在位置参数的中间。考虑这个更复杂的方法:

def my_method(a, b = 2, c = 3, d)
  p [a, b, c, d]
end

这里bc有默认值。如果您仅向此方法发送两个参数:

my_method(1, 4)

你会看到 ruby 打印[1, 2, 3, 4]

如果您发送三个参数:

my_method(1, 5, 6)

你会看到 ruby 打印[1, 5, 3, 6]

用文字描述这一点变得复杂和令人困惑。我会用变量和值来描述它。

首先1分配给a,然后6分配给d。这只保留具有默认值的参数。由于5尚未分配给值,因此它被赋予bc使用其默认值3

关键字参数

关键字参数遵循任何位置参数,并以逗号分隔,如位置参数:

my_method(positional1, keyword1: value1, keyword2: value2)

任何未提供的关键字参数都将使用方法定义中的默认值。如果给出关键字参数,该方法未列出,则会引发 ArgumentError。

块参数

block 参数从调用范围向方法发送闭包。

将消息发送给方法时,块参数总是最后一个。一个块使用do ... end或发送给一个方法{ ... }

my_method do
  # ...
end

或者:

my_method {
  # ...
}

do end优先级低于{ }

method_1 method_2 {
  # ...
}

在以下情况下发送块method_2

method_1 method_2 do
  # ...
end

发送块到method_1。请注意,在第一种情况下,如果使用圆括号,块将被发送到method_1

块将接受来自发送方法的参数。参数的定义类似于方法定义参数的方式。该块的参数进入| ... |开放do{

my_method do |argument1, argument2|
  # ...
end

阻止本地参数

您也可以;在块参数列表中声明块本地参数。分配给块本地参数不会覆盖调用程序范围内块的局部参数:

def my_method
  yield self
end

place = "world"

my_method do |obj; place|
  place = "block"
  puts "hello #{obj} this is #{place}"
end

puts "place is: #{place}"

这打印:

hello main this is block
place is world

因此,place块中的变量与块place外部的变量不同。; place从块参数中移除可以得到如下结果:

hello main this is block
place is block

数组到参数的转换

给定以下方法:

def my_method(argument1, argument2, argument3)
end

您可以使用*(或 splat)运算符将数组转换为参数列表:

arguments = [1, 2, 3]
my_method(*arguments)

或者:

arguments = [2, 3]
my_method(1, *arguments)

两者相当于:

my_method(1, 2, 3)

如果方法接受关键字参数,则 splat 运算符会将数组末尾的散列转换为关键字参数:

def my_method(a, b, c: 3)
end

arguments = [1, 2, { c: 4 }]
my_method(*arguments)

您也可以使用**(描述的下一个)将 Hash 转换为关键字参数。

如果数组中的对象数量与该方法的参数数量不匹配,则会引发 ArgumentError。

如果 splat 操作员在呼叫中首先出现,则必须使用括号来避免警告。

散列到关键字参数转换

给定以下方法:

def my_method(first: 1, second: 2, third: 3)
end

您可以使用**运算符将一个 Hash 转换为关键字参数:

arguments = { first: 3, second: 4, third: 5 }
my_method(**arguments)

或者:

arguments = { first: 3, second: 4 }
my_method(third: 5, **arguments)

两者相当于:

my_method(first: 3, second: 4, third: 5)

如果方法定义用于**收集任意关键字参数,则不会通过以下方式收集它们*

def my_method(*a, **kw)
  p arguments: a, keywords: kw
end

my_method(1, 2, '3' => 4, five: 6)

打印:

{:arguments=>[1, 2, {"3"=>4}], :keywords=>{:five=>6}}

与上面描述的 splat 操作符不同,**操作员没有公认的名称。

Proc 阻止转换

给定一个使用块的方法:

def my_method
  yield self
end

您可以使用&运算符将 proc 或 lambda 转换为块参数:

argument = proc { |a| puts "#{a.inspect} was yielded" }

my_method(&argument)

如果图示运算符在调用中首先出现,则必须使用括号来避免警告。

与上面描述的 splat 操作符不同,&操作员没有公认的名称。

方法查找

当您发送消息时,Ruby 会查找与接收者的消息名称相匹配的方法。方法存储在类和模块中,所以方法查找可以走这些,而不是对象本身。

以下是接收方类或模块的方法查找顺序R

  • 相反顺序的前置模块R
  • 对于R中的匹配方法
  • 所包含的模块R以相反的顺序排列

如果R是具有超类的类,则R直到找到一个方法才会重复此类。

一旦找到匹配,方法查找停止。

如果没有发现匹配,这从一开始就重复,但寻找method_missing。缺省值method_missing是 BasicObject#method_missing,它在调用时引发 NameError。

如果细化(实验性功能)处于活动状态,则方法查找会更改。有关详细信息,请参阅优化文档。

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct