Ruby 将一个函数传递给另一个函数并调用它
Ruby中的函数不是第一类对象,但我希望能够将对函数的引用传递到另一个函数中并执行它。如何做到这一点 例如:Ruby 将一个函数传递给另一个函数并调用它,ruby,Ruby,Ruby中的函数不是第一类对象,但我希望能够将对函数的引用传递到另一个函数中并执行它。如何做到这一点 例如: def run_a_function_twice(my_function) # Call the function once. # Call the function again. end def say_hello puts "HI!" end run_a_function_twice(say_hello) 我正在阅读文档,但不确定是否应该尝试lambda、procs
def run_a_function_twice(my_function)
# Call the function once.
# Call the function again.
end
def say_hello
puts "HI!"
end
run_a_function_twice(say_hello)
我正在阅读文档,但不确定是否应该尝试lambda、procs或call(我只熟悉其他语言调用的概念)这是通过通过块传递方法来完成的。这有几个语法 第一个语法使用yield,看起来像这样
def method1
puts "This is from method 1"
yield
end
def method2
puts "This is from method 2"
end
method1(){method2}
以上将输出
这来自方法1
这来自方法2
第二个选项使用以下语法
def method1(&block)
puts "This is from method 1"
block.call
end
def method2
puts "This is from method 2"
end
method1(){method2}
输出结果相同。通常,首选yield
语法,因为它更简洁,但也因为它的平均速度约为块.call
表示法的5倍
第三个选项是使用
send
语法,如下所示
def method1(method_name_string)
puts "This is from method 1"
send(method_name_string, 1, 2)
end
def method2(a,b)
puts "This is from method 2" + a.to_s + ' ' + b.to_s
end
method1("method2")
您还可以使用
lambda
或Proc.new
def method1(lmb)
puts "This is from method 1"
block.call "A string"
end
foo = lambda do |x|
puts x
end
method1(foo)
在这种情况下,你会看到
这来自方法1
字符串这是通过通过块传递方法来完成的。这有几个语法 第一个语法使用yield,看起来像这样
def method1
puts "This is from method 1"
yield
end
def method2
puts "This is from method 2"
end
method1(){method2}
以上将输出
这来自方法1
这来自方法2
第二个选项使用以下语法
def method1(&block)
puts "This is from method 1"
block.call
end
def method2
puts "This is from method 2"
end
method1(){method2}
输出结果相同。通常,首选yield
语法,因为它更简洁,但也因为它的平均速度约为块.call
表示法的5倍
第三个选项是使用
send
语法,如下所示
def method1(method_name_string)
puts "This is from method 1"
send(method_name_string, 1, 2)
end
def method2(a,b)
puts "This is from method 2" + a.to_s + ' ' + b.to_s
end
method1("method2")
您还可以使用
lambda
或Proc.new
def method1(lmb)
puts "This is from method 1"
block.call "A string"
end
foo = lambda do |x|
puts x
end
method1(foo)
在这种情况下,你会看到
这来自方法1
字符串您可以通过两种不同的方式执行此操作:
say_hello
与run_a_method_两次在同一范围内可用,例如,如果它们都是同一类上的实例方法。如果在另一个对象上定义了say\u hello
,您将执行例如some\u obj.send(:say\u hello)
您可以通过在方法名称后将参数指定给send
,为方法提供参数,例如jordan.send(:say_hello,“Donny”)
def yield_to_a_block_twice
yield
yield
end
yield_to_a_block_twice { say_hello }
这种语法也适用:
def call_a_block_twice(&block)
block.call
block.call
end
如果可能,您应该使用yield
(速度更快),但有时需要能够按名称引用块(例如,如果需要将其传递给另一个方法,或从另一个块中调用它),在这种情况下,需要将其设为命名参数(即def meth(arg1、arg2和block_name)
)
block、Proc和lambda之间的区别对Ruby新手来说是一个挑战,关于它们的文章很多,只有谷歌的“Ruby block Proc lambda”一文您可以通过两种不同的方式执行此操作:
say_hello
与run_a_method_两次在同一范围内可用,例如,如果它们都是同一类上的实例方法。如果在另一个对象上定义了say\u hello
,您将执行例如some\u obj.send(:say\u hello)
您可以通过在方法名称后将参数指定给send
,为方法提供参数,例如jordan.send(:say_hello,“Donny”)
def yield_to_a_block_twice
yield
yield
end
yield_to_a_block_twice { say_hello }
这种语法也适用:
def call_a_block_twice(&block)
block.call
block.call
end
如果可能,您应该使用yield
(速度更快),但有时需要能够按名称引用块(例如,如果需要将其传递给另一个方法,或从另一个块中调用它),在这种情况下,需要将其设为命名参数(即def meth(arg1、arg2和block_name)
)
block、Proc和lambda之间的区别对Ruby新手来说是一个挑战,关于它们的文章很多,只有谷歌的“Ruby block Proc lambda”一文通常在ruby中有块的概念,如果愿意的话,块就是匿名方法(闭包) 可以将块传递给任何方法。然后,该方法可以使用
yield
(与block\u给定?
)调用该方法/块,或使用和运算符将其引用到变量。后者可用于存储引用或将其传递给另一个方法
def call_it_twice
2.times {|i| yield(i) }
end
call_it_twice { puts "hello" }
# hello
# hello
call_it_twice {|i| puts "hello #{i}" }
# hello 0
# hello 1
def call_it_thrice &block
call_it_twice(&block)
block.call(2)
end
call_it_thrice {|i| puts "hello #{i}" }
# hello 0
# hello 1
# hello 2
您也可以传递一个literal方法,但这并不常见
class Foo
def hello
puts "world"
end
end
Foo.instance_methods(:hello)
# #<UnboundMethod: Foo#hello>
Foo.instance_method(:hello).call
# NoMethodError: undefined method `call' for #<UnboundMethod: Foo#hello>
Foo.instance_method(:hello).bind(Foo.new).call
# world
Foo.new.method(:hello)
# #<Method: Foo#hello>
Foo.new.method(:hello).call
# world
class-Foo
你好
“世界”
结束
结束
实例_方法(:hello)
# #
实例\方法(:hello).call
#NoMethodError:的未定义方法“调用”#
实例\方法(:hello).bind(Foo.new).call
#世界
Foo.new.method(:hello)
# #
Foo.new.method(:hello.call)
#世界
一个常见的方法是将array.map{x | x.downcase}
写成array.map(&:downcase)
(这是到_proc
的快捷方式,所以它是array.map(&:downcase.to _proc)
)
相对未知的是:数组。每个{x | puts x}
都与数组相同。每个(&method(:puts))
通常在ruby中有块的概念,如果愿意的话,它们是匿名方法(闭包)
可以将块传递给任何方法。然后,该方法可以使用yield
(与block\u给定?
)调用该方法/块,或使用和运算符将其引用到变量。后者可用于存储引用或将其传递给另一个方法
def call_it_twice
2.times {|i| yield(i) }
end
call_it_twice { puts "hello" }
# hello
# hello
call_it_twice {|i| puts "hello #{i}" }
# hello 0
# hello 1
def call_it_thrice &block
call_it_twice(&block)
block.call(2)
end
call_it_thrice {|i| puts "hello #{i}" }
# hello 0
# hello 1
# hello 2
您也可以传递一个literal方法,但这并不常见
class Foo
def hello
puts "world"
end
end
Foo.instance_methods(:hello)
# #<UnboundMethod: Foo#hello>
Foo.instance_method(:hello).call
# NoMethodError: undefined method `call' for #<UnboundMethod: Foo#hello>
Foo.instance_method(:hello).bind(Foo.new).call
# world
Foo.new.method(:hello)
# #<Method: Foo#hello>
Foo.new.method(:hello).call
# world
class-Foo