【问题标题】:Perl like anonymous subroutines in rubyPerl 喜欢 ruby​​ 中的匿名子例程
【发布时间】:2016-01-22 03:05:01
【问题描述】:

我是 ruby​​ 新手,并试图在 ruby​​ 中复制这个调用匿名子例程的 perl:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

# Make a reference to a subroutine
my $codes = {
   one => sub {
      say "This is code block one";
      say "And this is code block one's line two"
   },
};

for my $next_code ( keys %{ $codes } ) {
   # Execute anonymous subroutine
   &{ $codes->{ $next_code } };
}

我试过这个:

#!/usr/bin/ruby -w

codes = {
   one: puts "This is code block one"
        puts "And this is code block one's line two",
 }
codes.each do |next_code|
   next_code
end

但是,我得到语法错误。这可能吗,还是有另一种首选的 ruby​​ 方式?

更新:是的,这就像一个调度表。我将代码存储在哈希中并稍后运行该代码。

【问题讨论】:

  • 看起来您可能正在尝试实现调度表。如果是这样,最好在您的问题中提及这一点,以避免 XY 问题。在 Ruby 中可能有更好的方法,它采用与 Perl 完全不同的方法。
  • 你能用常用词(不是perl代码)解释一下你想做什么吗?
  • &{ $codes->{ $next_code } } 最好写$codes->{ $next_code }->()

标签: ruby perl


【解决方案1】:

Ruby 将Procs 作为匿名的第一类子例程对象。 Procs 可以通过将块传递给Proc::newKernel#procKernel#lambda 或使用“stabby lambda” lambda 文字语法来创建。

#!/usr/bin/env ruby

# Make a reference to a subroutine
codes = {
  one: -> {
    puts "This is code block one"
    puts "And this is code block one's line two"
  }
}

codes.each do |name, code|
  # Execute anonymous subroutine
  code.()
end

Ruby 中最广泛使用的匿名代码块形式是一种称为block 的构造,它实际上不是 一个对象,而只是一个句法构造。 Ruby 中的每个方法都只有一个可选的块参数,可以在花括号中传递,也可以在普通方法参数之后使用 do/end 关键字对。您可以在上面的代码中看到一个正在运行的块,它被传递给 Hash#each 迭代方法。

如果你有兴趣,这里是我的一个小玩具项目,它演示了在各种语言中使用一流的闭包,包括 Perl5 和 Perl6、Ruby、PHP、Python、ECMAScript、Smalltalk、Clojure、Scheme ,以及许多其他人:http://joergwmittag.github.io/lambdaconscarcdr/

【讨论】:

  • 关于 procs 的一个有趣的地方是它们可以(至少?)五种方式调用。假设f = ->s { puts "Say #{s}!" }。然后f.call('hey')f['hey']f.('hey')f.yield('hey')f === "hey"都打印"Say hey!"
  • 虽然“正常”的方式是使用call或其语法糖.()[]call 的过时别名,用于通过使用方括号作为假括号使调用 Proc 更像是方法调用。从 Ruby 1.9 开始,我们有 .() 表示法,它更好地服务于这个目的,IMO。 yield我不知道,我想是为了与Fibres的API兼容? === 对于在case 表达式和Enumerable#grep 中使用Procs 很有用,但可能不应该直接调用。注意:它们都是call 的别名,除了()call 的语法糖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
相关资源
最近更新 更多