在Ruby中与`if __name__ == '__main__'`等价的语句是什么?

116

我是Ruby的新手。我想从一个包含我想要继续单独使用的工具的模块中导入函数。在Python中,我只需要执行以下操作:

def a():
    ...
def b():
    ...
if __name__ == '__main__':
    a()
    b()

这使我能够运行该程序或导入它作为模块以单独使用 a() 和/或 b()。在Ruby中有类似的范例吗?


可能是重复的问题:如何从命令行运行 Ruby 库 - Andrew Grimm
3个回答

151

根据我在野外(虽然不多)看到的 Ruby,这不是标准的 Ruby 设计模式。模块和脚本应该保持分离,因此如果没有真正好的、干净的方法来做到这一点,我也不会感到惊讶。

编辑:找到了。

if __FILE__ == $0
    foo()
    bar()
end

但这绝对不是常见情况。


5
出于好奇,将模块和脚本分开保持的原因是什么? - Imagist
5
我认为这就是Ruby程序员所偏爱的方式。一个模块定义就是一个模块定义,如果你想对该模块执行某些操作,那很好,但你所执行的操作并不是一个模块定义。 - Matchu
10
不过,它对于测试东西非常方便--您可以将模块测试放在其中,并且可以直接从模块文件运行它们而无需任何包装。 - ebneter
3
另一种情况是:该脚本是一个单独的模块,旨在从命令行运行,但您还希望能够分部分测试它,并在单独的模块中进行测试。在这种情况下,NAME == $0非常有用。 - Confusion
16
我也没有见过这个,但它并不受到反对。官方的Ruby文档中使用了它:http://www.ruby-lang.org/en/documentation/quickstart/4/ - cflewis
显示剩余2条评论

12

如果调用堆栈为空,我们可以开始向右和左执行。我不知道这是否被传统或非传统方式使用,因为我接触 Ruby 已经有一个星期了。

if caller.length == 0
  # do stuff
end

概念证明:

文件:test.rb

#!/usr/bin/ruby                                                                 

if caller.length == 0
  puts "Main script"
end

puts "Test"

文件:shmest.rb

#!/usr/bin/ruby -I .                                                            

require 'test.rb'

puts "Shmest"

用法:

$ ./shmest.rb 
Test
Shmest

$ ./test.rb
Main script
Test

11
if $PROGRAM_NAME == __FILE__
  foo()
  bar()
end 

相对于此代码:

Rubocop 更倾向于使用它。

if __FILE__ == $0
    foo()
    bar()
end

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