I want to use if-else condition in one line. I have us开发者_如何学JAVAed the ternary operator, but doesn't seem to work. Any clues?
class Array
def painful_injection
each do |item|
sum = yield (defined?(sum).nil?) ? 0 : sum, item #pass the arguments to the block
end
sum
end
end
puts [1, 2, 3, 4].painful_injection {|sum, nxt_item| sum + nxt_item}
This gives me an error:
Error :undefined method `+' for false:FalseClass
There are a couple of problems here. One is that defined?
of some variable doesn't return nil
within an assignment to that variable e.g.
irb(main):012:0> some_new_var = defined?(some_new_var)
=> "local-variable"
You also need some extra parentheses due to operator precedence.
Finally, variables defined inside a block are only available inside that call to the block so when each
yields subsequent items the previous value of sum
would be lost.
Why not just set sum
to 0
outside of the each
e.g.
class Array
def painful_injection
sum = 0
each do |item|
sum = yield(sum, item) #pass the arguments to the block
end
sum
end
end
... but then just might as well just use normal inject
[1,2,3,4].inject(0) { |sum, item| sum + item }
so perhaps you need to clarify the problem you're trying to solve?
There are two errors here.
- Beware of operator priority. Use parenthesis when you are not sure
- If you don't define
sum
outside the block, thensum
won't preserve its value outside the blog.
Here's the code
class Array
def painful_injection
sum = 0
each do |item|
sum = yield((sum.zero? ? 0 : sum), item) # pass the arguments to the block
end
sum
end
end
puts [1, 2, 3, 4].painful_injection {|sum, nxt_item| sum + nxt_item}
I think this is a sollution to this specific case.
class Array
def painful_injection
sum = 0
each do |item|
sum = yield(sum,item)
end
sum
end
end
puts [1, 2, 3, 4].painful_injection {|sum, nxt_item| sum + nxt_item}
I hope this is what you're trying to achieve, I didn't get the inline if to work for the following reason:
If you use it like this:
sum = yield((defined?(sum) ? sum : sum = 0),item)
you get a problem because sum is defined but will become nil at some point and you cannot test it for defined? and nil? in the same line because the nil? test will fall over the fact that it's not defined.
So I think there is no solution to your problem.
精彩评论