开发者

how to if-else in one line in ruby?

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.

  1. Beware of operator priority. Use parenthesis when you are not sure
  2. If you don't define sum outside the block, then sum 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.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜