如何在Ruby中像在JavaScript中一样编写函数构建函数?
How to write a function-building function in Ruby just like in JavaScript?
我是一个 Ruby 初学者,目前正在努力寻找一种合适的方法来编写函数式 Ruby,就像我们在 JavaScript 中所做的那样。在 JavaScript 中,开发人员可以编写一个嵌套函数,该函数 returns 允许他们从通用函数创建更具体的函数的函数。哪个看起来:
function memberwiseOperate(opr){
return function(array){
return array.map(opr);
}
}
var modBy10 = function(a){return a%10} // Make an operator function
var memberwiseModBy10 = memberwiseOperate(modBy10); // Make a specific function from the function-buildinng function
var output1 = memberwiseModBy10([11,12,13,14,15]);
var output2 = memberwiseModBy10([31,32,33]);
从上面的代码中,JS 开发人员可以从函数 memberwiseOperate 中创建一个函数 memberwiseModBy10。他们还可以根据需要从 memberwiseOperate 创建尽可能多的其他成员操作函数。但我发现这很难在 Ruby.
中做同样的事情
如何在 Ruby 中编写函数构建函数来实现与上述 JavaScript 代码类似的功能?就像:
def memberwiseOperate(opr)
return Proc.new{ |array| array.map(opr) } # return a new function, how?
end
我可以在其中从 memberwiseOperate 创建一个函数,就像 JS 让我这样做一样:
modBy10 = Proc.new{|a| a%10}
memberwiseModBy10 = memberwiseOperat(modBy10) # Possible to create a function from a function?
output1 = memberwiseModBy10([11,12,13,14,15])
output2 = memberwiseModBy10([31,32,33])
在 Ruby 中是否有可能实现此目的的方法?
在ruby中你可以使用map
并传递一个块。例如:
array.map { |element| element % 10 }
或者,如果您愿意:
mod_by_10 = Proc.new { |a| a%10 }
array.map(&mod_by_10)
注意有两种map
:
map
没有副作用,map!
有副作用。
如果我明白你想做什么,那就很简单了
a = lambda{|x| x % 10}
[11,12,13,14,15].map(&a)
在 Ruby 中,函数不是第一个 class 公民。你不能传递它们。但是,您可以传递 lambda 和 Procs。
memberwise_operate = ->(func) { ->(array){ array.map(&func)} }
mod_by_10 = ->(a){ a % 10 }
memberwise_mod_by_10 = memberwise_operate.call(mod_by_10)
memberwise_mod_by_10.call([11,12,13,14,15]) # => [1, 2, 3, 4, 5]
memberwise_mod_by_10.call([31,32,33]) # => [1, 2, 3]
然而,这不是大多数人会写的方式 Ruby。 Ruby 是一种具有函数式元素的面向对象编程语言。
->(param){ puts param }
是以下的简称:
lambda{|param| puts parm }
PS:Proc 和 lambda 之间有两个显着的区别:
- return 在 lambda 中 returns 到调用者而 return 在 Proc returns 中来自调用函数。
- lambda 检查 Proc 不检查的参数数量。
出于这个原因,您应该默认使用 lambda,因为它将提供最不意外的路径。
有关 Procs、lambda 和块的更深入的文章,请阅读 this article。
在 Ruby 中几乎完全相同。为了更清楚地看到相似之处,让我们首先将您的代码重写为更现代的 ECMAScript:
const memberwiseOperate = opr => array => array.map(opr);
const modBy10 = a => a % 10; // Make an operator function
const memberwiseModBy10 = memberwiseOperate(modBy10); // Make a specific function from the function-building function
const output1 = memberwiseModBy10([11, 12, 13, 14, 15]);
const output2 = memberwiseModBy10([31, 32, 33]);
console.log(output1);
这就是翻译成 Ruby 时的样子:
memberwise_operate = -> opr { -> array { array.map(&opr) }}
mod_by_10 = -> a { a % 10 } # Make an operator function
memberwise_mod_by_10 = memberwise_operate.(mod_by_10) # Make a specific function from the function-building function
output1 = memberwise_mod_by_10.([11, 12, 13, 14, 15])
output2 = memberwise_mod_by_10.([31, 32, 33])
puts output1
如您所见,几乎唯一的区别是 Enumerable#map
采用块参数,而不是 Proc
,因此我们必须将 Proc
转换为块使用一元前缀 &
运算符。
我是一个 Ruby 初学者,目前正在努力寻找一种合适的方法来编写函数式 Ruby,就像我们在 JavaScript 中所做的那样。在 JavaScript 中,开发人员可以编写一个嵌套函数,该函数 returns 允许他们从通用函数创建更具体的函数的函数。哪个看起来:
function memberwiseOperate(opr){
return function(array){
return array.map(opr);
}
}
var modBy10 = function(a){return a%10} // Make an operator function
var memberwiseModBy10 = memberwiseOperate(modBy10); // Make a specific function from the function-buildinng function
var output1 = memberwiseModBy10([11,12,13,14,15]);
var output2 = memberwiseModBy10([31,32,33]);
从上面的代码中,JS 开发人员可以从函数 memberwiseOperate 中创建一个函数 memberwiseModBy10。他们还可以根据需要从 memberwiseOperate 创建尽可能多的其他成员操作函数。但我发现这很难在 Ruby.
中做同样的事情如何在 Ruby 中编写函数构建函数来实现与上述 JavaScript 代码类似的功能?就像:
def memberwiseOperate(opr)
return Proc.new{ |array| array.map(opr) } # return a new function, how?
end
我可以在其中从 memberwiseOperate 创建一个函数,就像 JS 让我这样做一样:
modBy10 = Proc.new{|a| a%10}
memberwiseModBy10 = memberwiseOperat(modBy10) # Possible to create a function from a function?
output1 = memberwiseModBy10([11,12,13,14,15])
output2 = memberwiseModBy10([31,32,33])
在 Ruby 中是否有可能实现此目的的方法?
在ruby中你可以使用map
并传递一个块。例如:
array.map { |element| element % 10 }
或者,如果您愿意:
mod_by_10 = Proc.new { |a| a%10 }
array.map(&mod_by_10)
注意有两种map
:
map
没有副作用,map!
有副作用。
如果我明白你想做什么,那就很简单了
a = lambda{|x| x % 10}
[11,12,13,14,15].map(&a)
在 Ruby 中,函数不是第一个 class 公民。你不能传递它们。但是,您可以传递 lambda 和 Procs。
memberwise_operate = ->(func) { ->(array){ array.map(&func)} }
mod_by_10 = ->(a){ a % 10 }
memberwise_mod_by_10 = memberwise_operate.call(mod_by_10)
memberwise_mod_by_10.call([11,12,13,14,15]) # => [1, 2, 3, 4, 5]
memberwise_mod_by_10.call([31,32,33]) # => [1, 2, 3]
然而,这不是大多数人会写的方式 Ruby。 Ruby 是一种具有函数式元素的面向对象编程语言。
->(param){ puts param }
是以下的简称:
lambda{|param| puts parm }
PS:Proc 和 lambda 之间有两个显着的区别:
- return 在 lambda 中 returns 到调用者而 return 在 Proc returns 中来自调用函数。
- lambda 检查 Proc 不检查的参数数量。
出于这个原因,您应该默认使用 lambda,因为它将提供最不意外的路径。 有关 Procs、lambda 和块的更深入的文章,请阅读 this article。
在 Ruby 中几乎完全相同。为了更清楚地看到相似之处,让我们首先将您的代码重写为更现代的 ECMAScript:
const memberwiseOperate = opr => array => array.map(opr);
const modBy10 = a => a % 10; // Make an operator function
const memberwiseModBy10 = memberwiseOperate(modBy10); // Make a specific function from the function-building function
const output1 = memberwiseModBy10([11, 12, 13, 14, 15]);
const output2 = memberwiseModBy10([31, 32, 33]);
console.log(output1);
这就是翻译成 Ruby 时的样子:
memberwise_operate = -> opr { -> array { array.map(&opr) }}
mod_by_10 = -> a { a % 10 } # Make an operator function
memberwise_mod_by_10 = memberwise_operate.(mod_by_10) # Make a specific function from the function-building function
output1 = memberwise_mod_by_10.([11, 12, 13, 14, 15])
output2 = memberwise_mod_by_10.([31, 32, 33])
puts output1
如您所见,几乎唯一的区别是 Enumerable#map
采用块参数,而不是 Proc
,因此我们必须将 Proc
转换为块使用一元前缀 &
运算符。