45、Ruby 编程中的预定义元素与实用快捷方式

Ruby 编程中的预定义元素与实用快捷方式

1. 预定义模块和类

当 Ruby 1.8 解释器启动时,会定义以下模块:
- Comparable
- FileTest
- Marshal
- Precision
- Enumerable
- GC
- Math
- Process
- Errno
- Kernel
- ObjectSpace
- Signal

同时,会定义以下类:
| 类名 | 类名 | 类名 | 类名 |
| — | — | — | — |
| Array | File | Method | String |
| Bignum | Fixnum | Module | Struct |
| Binding | Float | NilClass | Symbol |
| Class | Hash | Numeric | Thread |
| Continuation | IO | Object | ThreadGroup |
| Data | Integer | Proc | Time |
| Dir | MatchData | Range | TrueClass |
| FalseClass | MatchingData | Regexp | UnboundMethod |

还会定义以下异常类:
- ArgumentError
- NameError
- SignalException
- EOFError
- NoMemoryError
- StandardError
- Exception
- NoMethodError
- SyntaxError
- FloatDomainError
- NotImplementedError
- SystemCallError
- IOError
- RangeError
- SystemExit
- IndexError
- RegexpError
- SystemStackError
- Interrupt
- RuntimeError
- ThreadError
- LoadError
- ScriptError
- TypeError
- LocalJumpError
- SecurityError
- ZeroDivisionError

Ruby 1.9 增加了以下模块、类和异常:
- BasicObject
- FiberError
- Mutex
- VM
- Fiber
- KeyError
- StopIteration

你可以使用以下代码检查预定义的模块、类和异常:

# Print all modules (excluding classes)
puts Module.constants.sort.select {|x| eval(x.to_s).instance_of? Module}
# Print all classes (excluding exceptions)
puts Module.constants.sort.select {|x|
  c = eval(x.to_s)
  c.is_a? Class and not c.ancestors.include? Exception
}
# Print all exceptions
puts Module.constants.sort.select {|x|
  c = eval(x.to_s)
  c.instance_of? Class and c.ancestors.include? Exception
}

2. 顶级常量

Ruby 解释器启动时,除了前面列出的模块和类,还会定义以下顶级常量。定义了同名常量的模块仍可通过在前面加上 :: 来访问这些顶级常量。你可以使用以下命令列出顶级常量:

ruby -e 'puts Module.constants.sort.reject{|x| eval(x.to_s).is_a? Module}'

以下是一些顶级常量的介绍:
| 常量名 | 描述 |
| — | — |
| ARGF | 一个 IO 对象,可访问 ARGV 中指定的文件的虚拟串联,如果 ARGV 为空,则访问标准输入。它是 $< 的同义词。 |
| ARGV | 一个数组,包含命令行中指定的参数。它是 $* 的同义词。 |
| DATA | 如果程序文件中包含单独一行的 __END__ 标记,则该常量定义为一个流,可访问 __END__ 之后的文件行。如果程序文件中不包含 __END__ ,则该常量未定义。 |
| ENV | 一个行为类似于哈希的对象,可访问解释器的环境变量设置。 |
| FALSE | false 的弃用同义词。 |
| NIL | nil 的弃用同义词。 |
| RUBY_PATCHLEVEL | 一个字符串,表示解释器的补丁级别。 |
| RUBY_PLATFORM | 一个字符串,表示 Ruby 解释器的平台。 |
| RUBY_RELEASE_DATE | 一个字符串,表示 Ruby 解释器的发布日期。 |
| RUBY_VERSION | 一个字符串,表示解释器支持的 Ruby 语言版本。 |
| STDERR | 标准错误输出流。它是 $stderr 变量的默认值。 |
| STDIN | 标准输入流。它是 $stdin 变量的默认值。 |
| STDOUT | 标准输出流。它是 $stdout 变量的默认值。 |
| TOPLEVEL_BINDING | 一个 Binding 对象,表示顶级作用域中的绑定。 |
| TRUE | true 的弃用同义词。 |

3. 全局变量

Ruby 解释器预定义了许多全局变量,你可以在程序中使用。这些变量有一些特殊之处,有些名称中使用了标点符号( English.rb 模块定义了这些标点符号的英文替代名称,如果你想使用这些详细名称,可以在程序中添加 require 'English' ),有些是只读的,有些是线程局部的,还有一些是方法局部的。

你可以使用以下命令获取 Ruby 解释器预定义的全局变量的完整列表:

ruby -e 'puts global_variables.sort'

若要在列表中包含 English 模块的详细名称,可以尝试:

ruby -rEnglish -e 'puts global_variables.sort'

3.1 全局设置

这些全局变量保存配置设置,并指定 Ruby 程序运行环境的信息,如命令行参数:
| 变量名 | 描述 | 英文同义词 |
| — | — | — |
| $* | ARGV 常量的只读同义词。 | $ARGV |
| $$ | 当前 Ruby 进程的进程 ID,只读。 | $PID , $PROCESS_ID |
| $? | 最后终止的进程的退出状态,只读且线程局部。 | $CHILD_STATUS |
| $DEBUG , $-d | 如果命令行中设置了 -d --debug 选项,则设置为 true 。 | |
| $KCODE , $-K | 在 Ruby 1.8 中,该变量保存一个字符串,表示当前的文本编码,其值为 “NONE”、“UTF8”、“SJIS” 或 “EUC”,可以使用解释器选项 -K 设置该值。在 Ruby 1.9 中,该变量不再起作用,使用它会导致警告。 | |
| $LOADED_FEATURES , $" | 一个字符串数组,列出已加载的文件,只读。 | |
| $LOAD_PATH , $: , $-I | 一个字符串数组,保存使用 load require 方法加载文件时要搜索的目录。该变量是只读的,但你可以更改它所引用的数组的内容,例如在路径中追加或前置新目录。 | |
| $PROGRAM_NAME , $0 | 包含当前正在执行的 Ruby 程序的文件的名称。如果程序从标准输入读取,则值为 “-”;如果使用 -e 选项指定程序,则值为 “-e”。注意,这与 $FILENAME 不同。 | |
| $SAFE | 程序执行的当前安全级别,详细信息请参考相关内容。可以使用 -T 选项从命令行设置该变量的值,该变量的值是线程局部的。 | |
| $VERBOSE , $-v , $-w | 如果指定了 -v -w --verbose 命令行选项,则为 true ;如果指定了 -W0 ,则为 nil ;否则为 false 。你可以将该变量设置为 nil 以抑制所有警告。 | |

3.2 异常处理全局变量

以下两个全局变量在捕获异常时的 rescue 子句中很有用:
| 变量名 | 描述 | 英文同义词 |
| — | — | — |
| $! | 最后抛出的异常对象。也可以在 rescue 子句的声明中使用 => 语法访问异常对象,该变量的值是线程局部的。 | $ERROR_INFO |
| $@ | 最后一个异常的堆栈跟踪,相当于 $!.backtrace ,该值是线程局部的。 | $ERROR_POSITION |

3.3 流和文本处理全局变量

以下全局变量是 IO 流和影响文本处理 Kernel 方法默认行为的变量:
| 变量名 | 描述 | 英文同义词 |
| — | — | — |
| $_ | Kernel 方法 gets readline 最后读取的字符串,该值是线程局部和方法局部的。许多 Kernel 方法隐式地对 $_ 进行操作。 | $LAST_READ_LINE |
| $< | ARGF 流的只读同义词:一个类似 IO 的对象,可访问命令行中指定的文件的虚拟串联,如果未指定文件,则访问标准输入。 Kernel 读取方法(如 gets )从该流读取。注意,该流并不总是与 $stdin 相同。 | $DEFAULT_INPUT |
| $stdin | 标准输入流,该变量的初始值是常量 STDIN 。许多 Ruby 程序从 ARGF $< 读取,而不是 $stdin 。 | |
| $stdout , $> | 标准输出流,也是 Kernel 打印方法(如 puts print printf 等)的目标。 | $DEFAULT_OUTPUT |
| $stderr | 标准错误输出流,该变量的初始值是常量 STDERR 。 | |
| $FILENAME | 当前从 ARGF 读取的文件的名称,相当于 ARGF.filename ,只读。 | |
| $. | 当前输入文件中最后读取的行号,相当于 ARGF.lineno 。 | $NR , $INPUT_LINE_NUMBER |
| $/ , $-0 | 输入记录分隔符(默认为换行符), gets readline 默认使用该值来确定行边界。你可以使用 -0 解释器选项设置该值。 | $RS , $INPUT_RECORD_SEPARATOR |
| $\ | 输出记录分隔符,默认值为 nil ,但在使用 -l 解释器选项时设置为 $/ 。如果不为 nil ,则在每次调用 print (但不是 puts 或其他输出方法)后输出该分隔符。 | $ORS , $OUTPUT_RECORD_SEPARATOR |
| $, | print 参数之间的输出分隔符,也是 Array.join 的默认分隔符,默认值为 nil 。 | $OFS , $OUTPUT_FIELD_SEPARATOR |
| $; , $-F | split 使用的默认字段分隔符,默认值为 nil ,你可以使用 -F 解释器选项指定一个值。 | $FS , $FIELD_SEPARATOR |
| $F | 如果 Ruby 解释器使用 -a 选项以及 -n -p 选项调用,则定义该变量。它保存当前输入行的字段,由 split 返回。 | |

3.4 模式匹配全局变量

以下全局变量是线程局部和方法局部的,由任何 Regexp 模式匹配操作设置:
| 变量名 | 描述 | 英文同义词 |
| — | — | — |
| $~ | 最后一次模式匹配操作产生的 MatchData 对象,该值是线程局部和方法局部的。这里描述的其他模式匹配全局变量都由此派生。将该变量设置为新的 MatchData 对象会改变其他变量的值。 | $MATCH_INFO |
| $& | 最近匹配的文本,相当于 $~[0] ,只读、线程局部、方法局部,由 $~ 派生。 | $MATCH |
| $`` | 最后一次模式匹配中匹配之前的字符串,相当于 $~.pre_match ,只读、线程局部、方法局部,由 $~ 派生。 | $PREMATCH | | $’ | 最后一次模式匹配中匹配之后的字符串,相当于 $~.post_match ,只读、线程局部、方法局部,由 $~ 派生。 | $POSTMATCH | | $+ | 最后一次模式匹配中最后一个成功匹配的组对应的字符串,只读、线程局部、方法局部,由 $~ 派生。 | $LAST_PAREN_MATCH` |

3.5 命令行选项全局变量

Ruby 定义了许多与解释器命令行选项的状态或值对应的全局变量:
| 变量名 | 描述 |
| — | — |
| $-a | 如果指定了解释器选项 -a ,则为 true ;否则为 false ,只读。 |
| $-i | 如果未指定解释器选项 -i ,则为 nil 。否则,该变量设置为 -i 指定的备份文件扩展名。 |
| $-l | 如果指定了 -l 选项,则为 true ,只读。 |
| $-p | 如果指定了解释器选项 -p ,则为 true ;否则为 false ,只读。 |
| $-W | 在 Ruby 1.9 中,该全局变量指定当前的详细级别。如果使用了 -W0 选项,则为 0;如果使用了 -w -v --verbose 选项,则为 2;否则为 1,只读。 |

4. 预定义全局函数

Kernel 模块定义了许多作为全局函数的私有实例方法,这些方法必须以函数方式调用,无需显式的接收者对象,并且可以在任何地方调用。这些函数可以分为以下几类:

4.1 关键字函数

以下 Kernel 函数的行为类似于语言关键字:
- block_given?
- iterator?
- loop
- require
- callcc
- lambda
- proc
- throw
- catch
- load
- raise

4.2 文本输入、输出和操作函数

Kernel 定义了以下函数,其中大多数是 IO 方法的全局变体:
- format
- print
- puts
- sprintf
- gets
- printf
- readline
- p
- putc
- readlines

在 Ruby 1.8(但不是 1.9)中, Kernel 还定义了以下隐式对 $_ 操作的 String 方法的全局变体:
- chomp
- chomp!
- chop
- chop!
- gsub
- gsub!
- scan
- split
- sub
- sub!

4.3 操作系统方法

以下 Kernel 函数允许 Ruby 程序与操作系统进行交互:
- `
- fork
- select
- system
- trap
- exec
- open
- syscall
- test

4.4 警告、失败和退出

以下 Kernel 函数用于显示警告、抛出异常、使程序退出或注册程序终止时要运行的代码块:
- abort
- at_exit
- exit
- exit!
- fail
- warn

4.5 反射函数

以下 Kernel 函数是 Ruby 反射 API 的一部分:
- binding
- set_trace_func
- caller
- singleton_method_added
- eval
- singleton_method_removed
- global_variables
- singleton_method_undefined
- local_variables
- trace_var
- method_missing
- untrace_var
- remove_instance_variable

4.6 转换函数

以下 Kernel 函数尝试将其参数转换为新类型:
- Array
- Float
- Integer
- String

4.7 其他 Kernel 函数

以下其他 Kernel 函数不属于上述类别:
- autoload
- rand
- srand
- autoload?
- sleep

5. 用户定义的全局函数

在类或模块声明中使用 def 定义方法且未指定接收者对象时,该方法将作为 self (即正在定义的类或模块)的公共实例方法创建。而在顶级作用域(即不在任何类或模块中)使用 def 定义方法有两个重要区别:首先,顶级方法是 Object 的实例方法(即使 self 不是 Object );其次,顶级方法始终是私有的。

5.1 顶级 self :主对象

顶级方法成为 Object 的实例方法,但 self 是一个特殊的对象,称为 “主” 对象。主对象的类是 Object ,它有一个单例 to_s 方法,返回字符串 “main”。

顶级方法定义在 Object 中意味着它们会被所有对象(包括 Module Class )继承,并且(如果未被重写)可以在任何类或实例方法定义中使用。由于顶级方法是私有的,因此必须像函数一样调用,无需显式的接收者。通过这种方式,Ruby 在其严格的面向对象框架内模拟了过程式编程范式。

6. 实用提取和报告快捷方式

Ruby 受到脚本语言 Perl 的影响,包含许多全局函数,便于编写从文件中提取信息并生成报告的程序。在面向对象范式中,输入和输出函数是 IO 的方法,字符串操作函数是 String 的方法,但为了实用起见,有一些全局函数可以从预定义的输入和输出流进行读写。此外,许多这些函数隐式地对特殊的方法局部变量 $_ 进行操作,该变量保存从输入流读取的最后一行。

6.1 输入函数

全局函数 gets readline readlines 与同名的 IO 方法类似,但它们隐式地对 $< 流(也可作为常量 ARGF 使用)进行操作,并且隐式地设置 $_

$< 的行为类似于 IO 对象,但它不是 IO 对象。如果 ARGV 数组为空,则 $< STDIN 相同;如果 ARGV 不为空, $< 会依次读取 ARGV 中的文件。这意味着你的 Ruby 脚本可以在开始从 $< 读取之前修改 ARGV ,也可以在运行时向 ARGV 中添加其他文件。

6.2 已弃用的提取函数

在 Ruby 1.8 及更早版本中,全局函数 chomp chomp! chop chop! gsub gsub! scan split sub sub! 的行为与同名的 String 方法类似,但隐式地对 $_ 进行操作。这些全局函数在 Ruby 1.9 中已被移除,因此不应在新代码中使用。

6.3 报告函数

Kernel 定义了许多将输出发送到 $stdout 的全局函数:
- puts print printf putc 等同于 STDOUT 的同名方法。 puts 会在输出末尾追加换行符,而 print 不会自动追加换行符,但会在设置了 $\ 时追加输出记录分隔符。
- 全局函数 p 用于调试,它调用每个参数的 inspect 方法并将结果字符串传递给 puts 。如果需要 “漂亮打印” 调试输出,可以使用 pp 函数。
- printf 方法期望第一个参数是格式字符串,并将其余参数的值替换到该字符串中,然后输出结果。你也可以使用全局函数 sprintf 或其同义词 format 将结果格式化为字符串,而不将其发送到 $stdout

综上所述,Ruby 提供了丰富的预定义元素和实用快捷方式,这些功能在编写脚本和程序时非常有用,但在大型程序中应谨慎使用全局变量和函数,以避免代码的复杂性和不可维护性。通过合理运用这些特性,开发者可以更高效地完成各种任务。

7. 输入函数流程分析

下面我们通过 mermaid 格式的流程图来展示输入函数 gets readline readlines $< 流操作的流程:

graph TD;
    A[开始] --> B{ARGV 数组是否为空};
    B -- 是 --> C[$< 等同于 STDIN];
    B -- 否 --> D[使用 ARGV.shift 获取第一个文件名];
    D --> E[打开并读取该文件];
    E --> F{是否到达文件末尾};
    F -- 否 --> G[继续读取文件内容并设置 $_];
    G --> F;
    F -- 是 --> H{ARGV 中是否还有文件名};
    H -- 是 --> D;
    H -- 否 --> I[结束读取];
    C --> J[从 STDIN 读取内容并设置 $_];
    J --> K[结束读取];

这个流程图清晰地展示了 $< 流在不同情况下的读取逻辑。当 ARGV 为空时,直接从标准输入读取;当 ARGV 不为空时,依次读取 ARGV 中的文件,直到所有文件读取完毕。

8. 报告函数使用示例

以下是一些报告函数的使用示例,帮助你更好地理解它们的功能:

# 使用 puts 输出
puts "Hello, World!"

# 使用 print 输出
print "This is a test. "
print "Another line. ", "\n"

# 使用 printf 格式化输出
name = "John"
age = 30
printf "Name: %s, Age: %d\n", name, age

# 使用 p 进行调试输出
arr = [1, 2, 3]
p arr

# 使用 sprintf 格式化字符串
formatted_str = sprintf "The value is %.2f", 3.14159
puts formatted_str

在这个示例中,我们展示了 puts print printf p sprintf 函数的使用。 puts 会自动添加换行符, print 可以根据需要控制换行, printf 用于格式化输出, p 方便调试, sprintf 则用于格式化字符串而不直接输出。

9. 全局变量和函数的使用建议

虽然 Ruby 提供了丰富的全局变量和函数,但在使用时需要注意以下几点:
- 避免滥用 :在大型项目中,过多使用全局变量和函数会增加代码的耦合度,降低代码的可维护性。尽量将功能封装在类和模块中,遵循面向对象的设计原则。
- 注意线程安全 :部分全局变量是线程局部的,但仍需注意在多线程环境下的使用,避免出现数据竞争和不一致的问题。
- 兼容性问题 :一些全局变量和函数在不同版本的 Ruby 中可能存在差异,如 Ruby 1.8 和 1.9 中关于 chomp 等函数的变化。在编写代码时,要确保代码的兼容性。

10. 总结

本文详细介绍了 Ruby 编程中的预定义模块、类、顶级常量、全局变量和全局函数,以及实用的提取和报告快捷方式。通过合理运用这些元素,开发者可以更高效地编写 Ruby 脚本和程序。

10.1 主要内容回顾

  • 预定义元素 :包括模块、类、异常类、顶级常量等,这些元素在 Ruby 解释器启动时自动定义,为开发提供了基础支持。
  • 全局变量 :分为全局设置、异常处理、流和文本处理、模式匹配、命令行选项等几类,各有不同的用途和特点。
  • 全局函数 :涵盖关键字函数、文本输入输出和操作函数、操作系统方法、警告失败和退出函数、反射函数、转换函数和其他函数等类别,方便进行各种操作。
  • 快捷方式 :受 Perl 影响,提供了一些全局函数和对 $_ 的隐式操作,便于编写提取信息和生成报告的程序。

10.2 未来展望

随着 Ruby 语言的不断发展,可能会有更多的预定义元素和快捷方式被添加或改进。开发者可以持续关注 Ruby 的官方文档和社区动态,及时掌握新特性,提升开发效率和代码质量。

通过对这些知识的深入理解和合理运用,你可以更好地发挥 Ruby 的优势,编写出高质量、高效率的代码。希望本文能对你的 Ruby 编程学习和实践有所帮助。

【RIS 辅助的 THz 混合场波束斜视下的信道估计定位】在混合场波束斜视效应下,利用太赫兹超大可重构智能表面感知用户信道位置(Matlab代码实现)内容概要:本文围绕“IS 辅助的 THz 混合场波束斜视下的信道估计定位”展开,重点研究在太赫兹(THz)通信系统中,由于混合近场远场共存导致的波束斜视效应下,如何利用超大可重构智能表面(RIS)实现对用户信道状态信息和位置的联合感知精确估计。文中提出了一种基于RIS调控的信道参数估计算法,通过优化RIS相移矩阵提升信道分辨率,并结合信号到达角(AoA)、到达时间(ToA)等信息实现高精度定位。该方法在Matlab平台上进行了仿真验证,复现了SCI一区论文的核心成果,展示了其在下一代高频通信系统中的应用潜力。; 适合人群:具备通信工程、信号处理或电子信息相关背景,熟悉Matlab仿真,从事太赫兹通信、智能反射面或无线定位方向研究的研究生、科研人员及工程师。; 使用场景及目标:① 理解太赫兹通信中混合场域波束斜视问题的成因影响;② 掌握基于RIS的信道估计用户定位联合实现的技术路径;③ 学习并复现高水平SCI论文中的算法设计仿真方法,支撑学术研究或工程原型开发; 阅读建议:此资源以Matlab代码实现为核心,强调理论实践结合,建议读者在理解波束成形、信道建模和参数估计算法的基础上,动手运行和调试代码,深入掌握RIS在高频通信感知一体化中的关键技术细节。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值