layout: post
title: Ruby 中的各种稀奇古怪的关键字
category: posts
写在前面
Ruby 中有很多稀奇古怪的关键字,冷不丁的看到了一下还真不记得是个什么用法。这里就把我自己碰到的记录下来,方便下次查找 😜
1. _END_(END 两边分别有两个下划线)
如果一个文件包含这行代码,并且标记两边没有空白字符,Ruby 解释器会在此停止对该文件的处理。所以可以在该文件的余下部分可以包含任何内容(当然还是可以通过 IO 对象的 DATA 对其进行读取的)
# test.rb
def foo
puts 'bar'
end
foo()
__END__
puts 'balabala...'
# ruby test.rb => bar
2. #coding: utf-8文件编码的指定
告诉 Ruby 解释器该文件的编码(或者在执行 .rb 文件的时候手动指定 ruby -E utf-8)
3. _ENCODING_
这个是一个常量,存储了当前文件的字符编码。
# gbk.rb
# coding: GBK
puts __ENCODING__
# ruby gbk.rb => GBK
4. 1_000_000_000 千分符
1_000_000_000: 千分符(等同于1000000000)
5. <<HEAR 自定义字符串分界符(需要结束)
自定义分界符内的全部作为字符串的内容
# test.rb
puts <<GROCERY_LIST
1. Salad mix.
2. Strawberries.*
def foo
puts '这里是里面'
end
foo()
GROCERY_LIST
def foo2
puts '这里是外面'
end
foo2()
# ruby test.rb =>
1. Salad mix.
2. Strawberries.*
def foo
puts '这里是里面'
end
foo()
这里是外面
# 备注
# GROCERY_LIST 开始标示
# GROCERY_LIST 结束标示
6. `ls`
由`` 包裹住的会被传递给 Kernel.` 方法,会将文本当做一个操作系统的 shell 命令来执行(所以你也可以这样去调用 Kernel.`(......),效果相同),或者使用 system('ls') 也是可以的
# irb
`ls` # => "rubyconf.txt\ntest.rb\n"
Kernel.`'ls' # => "rubyconf.txt\ntest.rb\n"
system('ls') # => rubyconf.txt test.rb
=> true
这里捎带提一下 system、exec、`` 方法的区别,直接上代码 😊:
1. system
# test.rb
result = system("echo 'hello'")
puts 'foobar'
puts result
# ruby test.rb =>
hello
foobar
true
########## 这里是分割线 ############
# test2.rb
result = system("echo0 'hello'")
puts 'foobar'
puts result
# ruby test2.rb =>
sh: echo0: command not found
foobar
false
*总结:
用system执行终端命令,命令会被执行,命令执行成功返回 true,命令执行失败返回 false,代码会继续往下执行。
2. exec
# test.rb
exec("echo 'hello'")
puts 'foobar'
# ruby test.rb => hello
总结:
后面的 puts 'foobar' 并没有被执行,以exec方法引导执行的程序启动的新进程会覆盖当前进程,而退出脚本。所以用exec可以执行终端命令,命令会被执行,命令执行成功后面的代码就不再继续执行了,命令执行失败,程序会报错。
3. ``
# test.rb
result = `echo 'hello'`
puts 'foobar'
puts result
# ruby test.rb => hello
foobar
hello
总结:
通过将系统 shell 包含在符号``之间, 命令执行成功返回执行结果( string 对象),命令执行失败程序会报错。
7. === 条件相等性操作符
条件相等性操作符,一般用在 case 语句的目标值是否和某个 when 从句相匹配
case some_object
when /a regex/
# do something
when String
# do something
when 2..4
# do something
end
# 等同
if /a regex/ === some_object
# do something
elsif String === some_object
# do something
elsif (2..4) === some_object
# do something
end
# 所以
# irb
Integer === 1 # => true
(1..5) === 5 # => true
所以可以重写该方法用来在 case 语句中决定两者是否匹配
8. =~ 正则匹配
这个是用来匹配正则表达式的
"aaa0" =~ /\d/ => 3 # 返回起始位置,未匹配上返回 nil
9. <=> 顺序比较
1 <=> 2 # => -1
1 <=> 1 # => 0
2 <=> 1 # => 1
10. _FILE_ (Ruby 解释器正在执行的文件名称)
# test.rb
puts __FILE__
# ruby test.rb => test.rb
11. LINE (当前代码的行数(整数) 该代码属于 FILE 所代表的文件)
# test.rb
# 这里是一行注释
puts __LINE__
# ruby test.rb => 2
12. ::ARGV (常量前面加上两个冒号)
表示在全局域内寻找 ARGV 这个常量等同于 Object::ARGV (因为不存在针对常量的 ‘全局作用域’,所以常量会被定义在 Object 里)。
PS: 另外在提一下变量和常量的一个小区别:
# 1. 变量: 当 Ruby 解释器看到对变量的赋值时,变量已经存在了
a = 1 if false
puts a #=> nil
puts b #=> NameError!
# 2. 常量: 必须真正被赋值后常量才会存在
A = 1 if false
puts A #=> NameError!
未完待续...😄
Kenyon