开发者

Check if a variable is defined outside the block

Suppose we have n constants like:

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

I need to check in the block if they exists and are non empty.

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


This is the best way, in my opinion:

[: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

EDIT:

Things are a bit more complicated if you want to look up constants in a scope sensitive way (i.e not just top-level constants):

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


In your original code, i is a string, so it won't be empty.

I assume you're checking whether the constant with the name of i is empty, right? 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

Notes:

  • I've renamed i to const_name
  • Ruby tends to use raise rather than fail
  • You've got a fair bit of logic in one line. I'd be tempted to break it into two lines, one checking if the constant exists, and one checking if the string the constant refers to is empty. Better yet, make it into a method.
  • Multi-line blocks tend to use do ... end rather than { ... } (that's more for single lines. I think there's a SO question comparing the two, however - it's worth looking up because the two forms aren't totally identical)

Out of curiosity, which programming language were you using before using Ruby? Was it Perl?


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜