非常教程

Ruby 2.4参考手册

语言 | 3Language

Assignment

在 Ruby 中,赋值使用=(等号)字符。本例将数字5分配给本地变量v

v = 5

如果变量先前未被引用,则赋值会创建一个局部变量。

局部变量名称

局部变量名称必须以小写的 US-ASCII 字母或设置了8位的字符开头。通常,本地变量与 US-ASCII 兼容,因为键入它们的键存在于所有键盘上。

(Ruby 程序必须使用 US-ASCII 兼容的字符集编写,在这种字符集中,如果设置了8位,则表示扩展字符,Ruby 允许本地变量包含这些字符。)

局部变量名称可能包含字母,数字,_(下划线或下划线)或第八位设置的字符。

局部变量范围

一旦分配了本地变量名称 - 对该范围其余部分的所有名称使用都被认为是局部变量。

这里是一个例子:

1.times do
  a = 1
  puts "local variables in the block: #{local_variables.join ", "}"
end

puts "no local variables outside the block" if local_variables.empty?

这打印:

local variables in the block: a
no local variables outside the block

由于该块创建一个新的作用域,因此它内部创建的任何局部变量都不会泄漏到周围的作用域。

外部范围中定义的变量显示在内部范围内:

a = 0

1.times do
  puts "local variables: #{local_variables.join ", "}"
end

这打印:

local variables: a

您可以通过;在块的参数中列出它们来将块中的变量与外部范围隔离。有关示例,请参阅调用方法文档中的块局部变量文档。

另请参阅内核#local_variables,但请注意,for循环不会像块一样创建新的范围。

局部变量和方法

在 Ruby 中,局部变量名称和方法名称几乎完全相同。如果你还没有分配到其中一个不明确的名字,ruby 会假设你想调用一个方法。一旦你分配了名字,ruby 会假设你想引用一个局部变量。

分析器遇到赋值时创建局部变量,而不是在赋值时发生:

a = 0 if false # does not assign to a

p local_variables # prints [:a]

p a # prints nil

方法与局部变量名称之间的相似性会导致代码混淆,例如:

def big_calculation
  42 # pretend this takes a long time
end

big_calculation = big_calculation()

现在任何引用都big_calculation被认为是局部变量,并且会被缓存。要调用该方法,请使用self.big_calculation

您可以通过使用上面显示的空参数括号强制进行方法调用,或者使用类似的明确接收方来强制执行方法调用self.。如果方法的可见性不公开,则使用明确的接收方可能会引发 NameError。

另一个通常令人困惑的情况是使用修饰符时if

p a if a = 0.zero?

而非打印的“真”,你收到一个 NameError,“未定义的局部变量或方法a'”. Since ruby parses the bareleft of the,如果first and has not yet seen an assignment to一个it assumes you wish to call a method. Ruby then sees the assignment to了`,并会假设你引用一个本地方法。

这种混淆来自表达的乱序执行。首先分配局部变量 - 然后尝试调用不存在的方法。

变量实例

实例变量在同一对象的所有方法中共享。

实例变量必须以@(“at” 符号或商业地址)开头。否则,实例变量名称将按照规则作为局部变量名称。由于实例变量以@第二个字符开头,可能是一个大写字母。

这是一个实例变量用法的例子:

class C
  def initialize(value)
    @instance_variable = value
  end

  def value
    @instance_variable
  end
end

object1 = C.new "some value"
object2 = C.new "other value"

p object1.value # prints "some value"
p object2.value # prints "other value"

未初始化的实例变量的值为nil。如果您在启用警告的情况下运行 Ruby,您将在访问未初始化的实例变量时收到警告。

value方法可以访问该方法设置的值initialize,但只能访问同一个对象。

类变量

类变量在类,它的子类和它的实例之间共享。

类变量必须以@@(两个 “at” 符号)开头。名称的其余部分遵循与实例变量相同的规则。

这里是一个例子:

class A
  @@class_variable = 0

  def value
    @@class_variable
  end

  def update
    @@class_variable = @@class_variable + 1
  end
end

class B < A
  def update
    @@class_variable = @@class_variable + 2
  end
end

a = A.new
b = B.new

puts "A value: #{a.value}"
puts "B value: #{b.value}"

这打印:

A value: 0
B value: 0

继续相同的例子,我们可以使用任何一个类中的对象进行更新,并且该值是共享的:

puts "update A"
a.update

puts "A value: #{a.value}"
puts "B value: #{b.value}"

puts "update B"
b.update

puts "A value: #{a.value}"
puts "B value: #{b.value}"

puts "update A"
a.update

puts "A value: #{a.value}"
puts "B value: #{b.value}"

这打印:

update A
A value: 1
B value: 1
update B
A value: 3
B value: 3
update A
A value: 4
B value: 4

访问未初始化的类变量将引发 NameError 异常。

请注意,类有实例变量,因为类是对象,所以尽量不要混淆类和实例变量。

全局变量

全局变量无处不在。

全局变量以$(美元符号)开头。名称的其余部分遵循与实例变量相同的规则。

这里是一个例子:

$global = 0

class C
  puts "in a class: #{$global}"

  def my_method
    puts "in a method: #{$global}"

    $global = $global + 1
    $other_global = 3
  end
end

C.new.my_method

puts "at top-level, $global: #{$global}, $other_global: #{$other_global}"

这打印:

in a class: 0
in a method: 0
at top-level, $global: 1, $other_global: 3

未初始化的全局变量的值为nil

Ruby 有一些特殊的全局变量,其取决于上下文的行为有所不同,例如正则表达式匹配变量或分配给它时有副作用。详细信息请参阅全局变量文档。

分配方法

您可以定义像分配一样的方法,例如:

class C
  def value=(value)
    @value = value
  end
end

c = C.new
c.value = 42

使用赋值方法可以让程序看起来更漂亮。当分配给实例变量时,大多数人使用 Module#attr_accessor:

class C
  attr_accessor :value
end

使用方法分配时,您必须始终有一个接收器。如果你没有接收器,Ruby假定你正在分配一个局部变量:

class C
  attr_accessor :value

  def my_method
    value = 42

    puts "local_variables: #{local_variables.join ", "}"
    puts "@value: #{@value.inspect}"
  end
end

C.new.my_method

这打印:

local_variables: value
@value: nil

要使用分配方法,您必须设置接收器:

class C
  attr_accessor :value

  def my_method
    self.value = 42

    puts "local_variables: #{local_variables.join ", "}"
    puts "@value: #{@value.inspect}"
  end
end

C.new.my_method

这打印:

local_variables:
@value: 42

缩写赋值

您可以混合几个操作员和任务。要将1添加到您可以编写的对象:

a = 1

a += 2

p a # prints 3

这相当于:

a = 1

a = a + 2

p a # prints 3

您可以使用以下运算符是这样的:+-*/%**&|^<<>>

还有||=&&=。如果值是nilfalse当后者进行赋值时,前者进行赋值,如果该值不是nilfalse

这里是一个例子:

a ||= 0
a &&= 1

p a # prints 1

注意,这两个运营商更像a || a = 0a = a || 0

隐式数组赋值

分配时可以通过列出多个值来隐式创建一个数组:

a = 1, 2, 3

p a # prints [1, 2, 3]

这隐含地创建一个数组。

您可以*在分配时使用或 “splat” 运算符或解压缩数组。这与多次分配类似:

a = *[1, 2, 3]

p a # prints [1, 2, 3]

您可以在任务右侧的任何地方摔打:

a = 1, *[2, 3]

p a # prints [1, 2, 3]

多重分配

您可以将右侧的多个值分配给多个变量:

a, b = 1, 2

p a: a, b: b # prints {:a=>1, :b=>2}

在下面的章节中,任何使用“变量”的地方都可以使用赋值方法,实例,类或全局:

def value=(value)
  p assigned: value
end

self.value, $global = 1, 2 # prints {:assigned=>1}

p $global # prints 2

您可以使用多个赋值就地交换两个值:

old_value = 1

new_value, old_value = old_value, 2

p new_value: new_value, old_value: old_value
# prints {:new_value=>1, :old_value=>2}

如果赋值右侧的值比左侧的变量多,则会忽略额外的值:

a, b = 1, 2, 3

p a: a, b: b # prints {:a=>1, :b=>2}

您可以使用*它在作业的右侧收集额外的值。

a, *b = 1, 2, 3

p a: a, b: b # prints {:a=>1, :b=>[2, 3]}

*可以在左侧的任意位置出现:

*a, b = 1, 2, 3

p a: a, b: b # prints {:a=>[1, 2], :b=>3}

但你只能*在任务中使用一个。

数组分解

像方法参数中的数组分解一样,您可以在使用括号进行赋值时分解数组:

(a, b) = [1, 2]

p a: a, b: b # prints {:a=>1, :b=>2}

您可以将数组分解为更大的多个赋值的一部分:

a, (b, c) = 1, [2, 3]

p a: a, b: b, c: c # prints {:a=>1, :b=>2, :c=>3}

由于每个分解都被认为是它自己的多重赋值,因此可以用它*来收集分解中的参数:

a, (b, *c), *d = 1, [2, 3, 4], 5, 6

p a: a, b: b, c: c, d: d
# prints {:a=>1, :b=>2, :c=>[3, 4], :d=>[5, 6]}
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