检查是否在块外定义了变量

时间:2010-09-19 12:53:06

标签: ruby

假设我们有n个常量,如:

FOO = 'foo'
BAR = 'bar'
...

我需要在块中检查它们是否存在且非空。

%w(FOO BAR FOOBAR).each {|i|
  # this doesn't work
  fail "#{i} is missing or empty" if (! defined?(i) || i.empty?)
}

3 个答案:

答案 0 :(得分:3)

在我看来,这是最好的方式:

[:FOO, :BAR, :FOOBAR].each do |i|
    raise "constant #{i} not defined" unless Object.const_defined?(i)

    puts "constant #{i} exists and has value #{Object.const_get(i)}"
end

编辑:

如果你想以范围敏感的方式查找常量(即不仅仅是顶级常量),事情就会复杂一些:

def const_receiver
    is_a?(Module) ? self : class << self; self; end
end

[:FOO, :BAR, :FOOBAR].each do |i|
    raise "constant #{i} not defined" unless const_receiver.const_defined?(i)

    puts "constant #{i} exists and has value #{const_receiver.const_get(i)}"
end

答案 1 :(得分:0)

在原始代码中,i是一个字符串,因此它不会为空。

我假设您正在检查名为i的常量是否为空,对吧? This is not a pipe.

%w(FOO BAR FOOBAR).each do |const_name|
  raise "#{const_name} is missing or empty" if (! eval("defined?#{const_name}") || eval(const_name).empty?)
end

注意:

  • 我已将i重命名为const_name
  • Ruby倾向于使用raise而不是fail
  • 你在一行中有一些逻辑。我很想把它分成两行,一行检查常量是否存在,另一行检查常量引用的字符串是否为空。更好的是,把它变成一种方法。
  • 多行块倾向于使用do ... end而不是{ ... }(对于单行来说更多。我认为比较两者有一个问题但是 - 它值得查找,因为这两种形式都不是完全相同)

出于好奇,你在使用Ruby之前使用了哪种编程语言?是Perl吗?

答案 2 :(得分:-1)

BAR = 'bar'
%w(FOO BAR FOOBAR).each {|i|
  begin
    eval(i)
  rescue NameError=>e
    puts e
  end
}