Ruby 方法
Ruby 方法
Section titled “Ruby 方法”Ruby 方法是执行特定任务的代码块。它们类似于其他编程语言中的函数,用于将一个或多个可重复的语句打包成一个单元,从而提高代码的可重用性和组织性。
按照约定,方法名称应以小写字母或下划线开头。如果方法名称以大写字母开头,Ruby 可能会将其解释为常量,从而导致解析错误。
方法必须先定义后调用;否则,Ruby 将引发 NoMethodError 异常。
定义方法的语法
Section titled “定义方法的语法”def method_name(parameter1, parameter2, ...) # 表达式(方法体) # ...end一个没有参数的简单方法:
#!/usr/bin/env rubydef greet puts "Hello, Ruby!"end一个带参数的方法:
#!/usr/bin/env rubydef personalize_greeting(name) puts "Hello, #{name}!"end默认参数值:
Section titled “默认参数值:”您可以为参数设置默认值。如果在调用方法时没有为这些参数提供实参 (arguments),则使用这些默认值。
#!/usr/bin/env rubydef greet_with_default(name = "World") puts "Hello, #{name}!"end
greet_with_default # 输出: Hello, World!greet_with_default("Alice") # 输出: Hello, Alice!要调用方法,只需使用其名称即可。如果方法需要实参 (arguments),则提供它们。
#!/usr/bin/env rubydef say_hello puts "Hello!"end
def add(a, b) puts a + bend
# 调用方法say_hello # 如果没有实参,可以不使用括号调用
add(5, 3) # 使用实参调用add 10, 20 # 在不引起歧义的情况下,括号通常是可选的如果一个方法需要特定数量的实参,而您使用不同数量的实参调用它,Ruby 将引发 ArgumentError 异常。
带默认值的示例:
Section titled “带默认值的示例:”#!/usr/bin/env ruby
def favorite_languages(lang1 = "Ruby", lang2 = "Python") puts "My favorite programming language is #{lang1}." puts "My second favorite is #{lang2}."end
favorite_languages("JavaScript", "Go") # 使用提供的实参puts "---"favorite_languages("Rust") # lang1 是 "Rust",lang2 使用默认值 "Python"puts "---"favorite_languages # 使用两个默认值这将产生:
My favorite programming language is JavaScript.My second favorite is Go.---My favorite programming language is Rust.My second favorite is Python.---My favorite programming language is Ruby.My second favorite is Python.方法的返回值
Section titled “方法的返回值”Ruby 中的每个方法都隐式返回其方法体中最后一个求值表达式的值。
#!/usr/bin/env rubydef simple_calculator(a, b) sum = a + b difference = a - b difference # 这是最后一个求值表达式,因此它被返回end
result = simple_calculator(10, 4)puts "Result (difference): #{result}" # 输出: Result (difference): 6return 语句
Section titled “return 语句”return 语句可用于显式退出方法并返回一个或多个值。如果 return 没有带表达式使用,它将返回 nil。如果提供了多个表达式,return 将返回一个包含这些值的数组。
returnreturn expressionreturn expr1, expr2, expr3#!/usr/bin/env rubydef get_coordinates x = 10 y = 20 z = 30 return x, y, z # 返回一个数组 [10, 20, 30]end
def get_status(code) return "OK" if code == 200 return "Error" # 如果 code 不是 200,则隐式返回 "Error"end
coords = get_coordinatesputs "Coordinates: #{coords.inspect}" # 输出: Coordinates: [10, 20, 30]
status_ok = get_status(200)puts "Status for 200: #{status_ok}" # 输出: Status for 200: OK
status_err = get_status(404)puts "Status for 404: #{status_err}" # 输出: Status for 404: Error可变数量的参数(Splat 运算符)
Section titled “可变数量的参数(Splat 运算符)”Ruby 允许方法使用 splat 运算符 (*) 接受可变数量的实参。当在方法定义中使用时,* 将任何剩余的实参收集到一个数组中。
#!/usr/bin/env rubydef display_items(category, *items) puts "Category: #{category}" puts "Number of items: #{items.length}" items.each_with_index do |item, index| puts " Item #{index + 1}: #{item}" endend
display_items("Fruits", "Apple", "Banana", "Orange")puts "---"display_items("Colors", "Red", "Green")puts "---"display_items("Tools") # items 将是一个空数组这将产生:
Category: FruitsNumber of items: 3 Item 1: Apple Item 2: Banana Item 3: Orange---Category: ColorsNumber of items: 2 Item 1: Red Item 2: Green---Category: ToolsNumber of items: 0Ruby 方法也可以接受关键字参数,这些参数在调用方法时通过名称指定。这可以使方法调用更具可读性,尤其是在参数或布尔标志很多的情况下。
#!/usr/bin/env rubydef create_user(name:, email:, admin: false, notify: true) puts "Creating user: #{name}" puts "Email: #{email}" puts "Admin: #{admin}" puts "Notify: #{notify}" # ... 创建用户的逻辑 ...end
create_user(name: "Alice", email: "alice@example.com")puts "---"create_user(name: "Bob", email: "bob@example.com", admin: true, notify: false)
# 使用双 splat (**) 处理任意数量的关键字参数def process_options(user_id, **options) puts "Processing for user: #{user_id}" options.each do |key, value| puts " Option #{key}: #{value}" endend
process_options(101, theme: "dark", layout: "compact", show_help: true)类方法是定义在类本身上的方法,而不是定义在类的实例上。它们通常用于工厂方法或与类相关的工具函数。
您可以通过在类定义中将方法名称前加上 self. 或类本身名称来定义类方法。
#!/usr/bin/env rubyclass Utility # 实例方法 def instance_method puts "This is an instance method." end
# 使用 self. 定义的类方法 def self.class_method_one puts "This is class_method_one." end
# 使用类名定义的类方法 def Utility.class_method_two puts "This is class_method_two." endend
# 直接在类上调用类方法Utility.class_method_oneUtility.class_method_two
# 要调用实例方法,您需要一个实例util_instance = Utility.newutil_instance.instance_method默认情况下,在类内部定义的方法是公共的 (public)。在顶层(任何类或模块之外)定义的方法将成为 Object 类的私有实例方法。
Ruby 的 alias 和 alias_method
Section titled “Ruby 的 alias 和 alias_method”alias 关键字为现有方法或全局变量创建一个别名。不能在方法体内部定义别名。当一个方法被赋予别名时,该别名指向该方法在别名创建时的定义,即使原始方法后来被覆盖也是如此。
alias_method 是一个方法(通常在类/模块内部使用),它为方法实现相同的功能,因其灵活性(例如,它可以接受符号或字符串作为实参)而常被优先使用。
alias new_method_name old_method_namealias new_global_variable_name old_global_variable_name
# 在类/模块内部:alias_method :new_method_name, :old_method_name#!/usr/bin/env rubyclass Greeter def welcome(name) "Hello, #{name}!" end
alias_method :greet, :welcome # 为实例方法创建别名end
my_greeter = Greeter.newputs my_greeter.welcome("Original")puts my_greeter.greet("Alias")
$global_var = "Initial Global"alias $gvar $global_var # 为全局变量创建别名puts $gvar禁止为内置的编号全局变量(如 $1, $2)创建别名。覆盖核心全局变量可能导致意外行为。
Ruby 的 undef 和 undef_method
Section titled “Ruby 的 undef 和 undef_method”undef 关键字取消方法的定义,使其不再可调用。它不能出现在方法体内部。
undef_method 是其基于方法对应的版本,通常在类/模块内部使用。
undef method_name
# 在类/模块内部:undef_method :method_name#!/usr/bin/env rubyclass Calculator def add(a, b) a + b end
def subtract(a, b) a - b endend
calc = Calculator.newputs calc.add(5, 3) # 输出: 8
class Calculator undef_method :add # 取消定义 'add' 方法end
# calc.add(7, 2) # 现在这将引发 NoMethodError 异常puts calc.subtract(10, 4) # 输出: 6使用 undef 和 alias 可以修改类的接口,可能独立于其超类 (superclass)。但是,必须小心,因为如果方法被取消定义,类内部调用 self 的方法可能会失效。