Ruby中是否有goto语句?

18

有没有一种方式可以从指定的行开始,类似于goto语句?


10
必备的xkcd漫画:http://xkcd.com/292/ - LiraNuna
1
你想知道的特别原因是什么? - Thom Smith
我知道你可以在rspec中实现。可以查看源代码。 - Translunar
5个回答

28
首先,它应该是陈述句而不是命令。其次,请参阅ruby-goto。第三,注意:

类别:库/邪恶


13
哇,"类别:图书馆/邪恶"。 - LiraNuna
3
起初我以为这只是个玩笑,但实际上确实有一个类别:Library/Evil。目前它包括之前提到的ruby-goto,以及segfault4r:“它是一个强制产生分段错误的模块”。 - Paul

4

有一个Ruby命令行开关-x

 -x[directory]  告诉Ruby脚本嵌入在消息中。
                先导垃圾将被丢弃,直到第一个以“#!”开头并包含字符串“ruby”的脚本。该行上任何有意义的开关都将被应用。必须使用EOF、^D(控制-D)、^Z(控制-Z)或保留字__END__指定脚本的结尾。如果指定了目录名称,Ruby将在执行脚本之前切换到该目录。

顺便说一句,我很确定ruby-goto是个玩笑。我不认为下载链接曾经起过作用。还是我只能指向它并保持沉默?我从来不知道...

我喜欢Ryan在宣布ruby-goto后的下一行:

敬请期待下一个邪恶模块... ruby-malloc!祝你愉快。

Ryan显然是个天才。


2

goto lib(跳转库)仍然存在 :D https://rubygems.org/gems/goto/versions/0

保留整个 gem 以备后人参考:

STACK = []

class Label
  attr_accessor :name;
  attr_accessor :block;

  def initialize(name, block);
    @name  = name
    @block = block
  end

  def ==(sym)
    @name == sym
  end
end

class Goto < Exception;
  attr_accessor :label
  def initialize(label); @label = label; end
end

def label(sym, &block)
  STACK.last << Label.new(sym, block)
end

def frame_start
  STACK << []
end

def frame_end
  frame = STACK.pop
  idx   = 0

  begin
    for i in (idx...frame.size)
      frame[i].block.call if frame[i].block
    end
  rescue Goto => g
    idx = frame.index(g.label)
    retry
  end
end

def goto(label)
  raise Goto.new(label)
end

2

我不相信会有这样的事情发生(而且,凭良心讲,它不应该发生)。

但是如果你真的想要,可以使用goto模块,不过这需要一些折磨自己的精神。


0
我试着创建了一个实现其功能的要点,这就是它的运行方式
我的库的工作示例:
label_stack_main do
  x = 0

  label(:increment) do
    x += 1
    goto :example
  end

  label(:example) do
    puts x
    goto :increment if x < 10
  end
  
  label(:start) do
    goto :example
  end
end

并且它的输出:

$ ruby example.rb
1
2
3
4
5
6
7
8
9
10

请注意,我的库在任何情况下都不使用异常。 另外,请注意,Ruby团队没有将goto原生地实现到语言中的原因是,我做这个只是为了好玩 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接