问题
I find myself using PHP-like loops a lot in Ruby and it feels wrong when the rest of the language is so neat. I wind up with code like this:
conditions_string = ''
zips.each_with_index do |zip, i|
conditions_string << ' OR ' if i > 0
conditions_string << "npa = ?"
end
# Now I can do something with conditions string
I feel like I should be able to do something like this
conditions_string = zips.each_with_index do |zip, i|
<< ' OR ' if i > 0
<< "npa = ?"
end
Is there a 'Neat' way to set a variable with a block in Ruby?
回答1:
You don't seem to be accessing zip
in your loop, so the following should work:
conditions_string = (['npa = ?'] * zips.length).join(' OR ')
If you need access to zip
, then you could use:
conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')
回答2:
Since you don't actually use the value of zip, I'd suggest
zips.map {|zip| "npa = ?" }.join(" OR ")
but in general I'd suggest looking at the Enumerable#inject function to avoid this kind of loops.
回答3:
The first thing I thought of was this:
a = %w{array of strings} => ["array", "of", "strings"]
a.inject { |m,s| m + ' OR ' + s } => "array OR of OR strings"
But that can be done with just
a.join ' OR '
And while I think you will need that construct soon, to duplicate your exact example I might just use:
([' npa = ? '] * a.size).join 'OR'
回答4:
Although others have given more idiomatic solutions to your specific problem, there's actually a cool method Object#instance_eval
, which is a standard trick that many Ruby DSLs use. It sets self
to the receiver of instance_eval
inside its block:
Short example:
x = ''
x.instance_eval do
for word in %w(this is a list of words)
self << word # This means ``x << word''
end
end
p x
# => "thisisalistofwords"
It doesn't pervasively cover everything in the way Perl's $_
does, but it allows you to implicitly send methods to one single object.
回答5:
In 1.8.7+ you can use each_with_object
It replaces DigitalRoss's 'inject' idiom with this:
a = %w{hello my friend} => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " } => "hello NOT my NOT friend NOT"
来源:https://stackoverflow.com/questions/1829621/setting-variables-with-blocks-in-ruby