2

going through ruby monk and once in a while they throw out a code from the left field with unfamiliar syntaxes:

 def compute(xyz)
   return nil unless xyz
   xyz.map {|a,b| !b.nil? ? a + b : a}
 end

Can somebody explain these three uses? 1) The exclamation before the object 2) The additional question mark 3) The colon usage within the lambda

Xavier
  • 323
  • 3
  • 10
  • 1
    The `!` is just `'not`'. `!b.nil? ? a + b : a` (a "ternary" operation) is shorthand for `if !b.nil?; a+b; else; b; end`, which is better expressed `if b.nil?; a; else; a+b; end`. – Cary Swoveland Jan 11 '15 at 00:07
  • `! - not` `? - istrueorfalse` `a+b : a -- options`. This `!b.nil? ? a + b : a` is basically called ternary operation. – vjdhama Jan 11 '15 at 00:08
  • @CarySwoveland I'd disagree; I think a ternary makes a lot more sense here, e.g., `b.nil? ? a : a+b` is quite a bit easier to reason about, IMO. – Dave Newton Jan 11 '15 at 00:22
  • @Xavier Some basic Ruby operator and naming convention research would clear all of this up immediately. Plus it's technically a block, not a lambda (e.g., lambdas are objects, blocks are a syntactical element, etc.) – Dave Newton Jan 11 '15 at 00:25
  • @DaveNewton In my opinion `if b.nil? then a else a+b end` makes even more sense for non-programmer. Well, in most cases it is matter of tastes. I explained other case here: http://stackoverflow.com/a/27882720/2597260 – Darek Nędza Jan 11 '15 at 00:41
  • @DaveNewton , we do not disagree. I just meant that if you go with `if..end`, I would prefer `if b.nil?...` to `if !b.nil?...`. I would use the ternary operation, but with `b.nil?...`. – Cary Swoveland Jan 11 '15 at 00:43
  • @DarekNędza By definition if you're writing code you're a programmer. Short ternaries are almost more readable then extra keywords, but since it's a matter of opinion, we'll have to agree to disagree. – Dave Newton Jan 11 '15 at 00:43
  • @CarySwoveland I think you meant me; I misunderstood the point you were making :) Sorry! – Dave Newton Jan 11 '15 at 00:44
  • @DaveNewton I guess a term "non-programmer" was bad. If you are a beginner programmer or you programmed in a verbose language like Pascal or Ada, `if...end`-like syntax will make more sense to you. `>:``<:@.odd` - this is an example from J language. It is like "short ternaries" (2 arguments and not verbose syntax). J support more verbose syntax. Previous example may look something like this(`\n` as a newline): `if. odd n \n do. <: n \n else. >: n end.`. I think most programmers are will understand 2nd example. The same goes for `if..end` vs `?:`. – Darek Nędza Jan 11 '15 at 11:39

3 Answers3

6

! is a just a not operator.

b.nil? is a method that checks the value for b is nil or not. Returns a boolean.

!b.nil? ? a + b : a is a ternary operation is action. It works like this :

if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this 

which is equivalent of saying

if a then b else c end

So relating with above statement if !b.nil? is true answer is a+b else it is a.

Read more here

Community
  • 1
  • 1
vjdhama
  • 4,878
  • 5
  • 33
  • 47
  • @Xavier Glad i could be of help. Please accept the answer so as to remove it from list of unanswered questions. – vjdhama Jan 11 '15 at 01:49
2

1) !, negations - it changes every object except nil and false to false (other objects into true) 2) name? should return false(false and nil) or true value (everything else). In most cases it will be true or false objects.
Methods with with ? at the end suggest that they are predicates. In your example nil? checks if object is nil. In other language you may find something like this: is_nil.
Other examples:

[].empty? # true 
3.zero? # false
0.zero? # true

3) The colon in your example is part of a ternary if.

'cond' ? 'true value' : 'false value'

is similar to:

if 'cond'
'true value'
else
'false value'
end

One difference between ?: and if else is precedence:

def foo a
a # just return a
end
foo 2 ? 3 : 4
# => 3
foo if 2 then 3 else 4 end
# error

In the last example Ruby wanted to run function1 if condition but it found function if condition #some garbage, so Ruby raised an error.

Darek Nędza
  • 1,420
  • 1
  • 12
  • 19
0
  1. The exclamation before the object :

    !x means negation of x, if x is true, then !x means false and vice-versa

  2. The additional question mark :

    x ? y : z

    means that if x is true, then return y, else return z

  3. The colon usage within the lambda

    I explained in the 2. above

A human being
  • 1,220
  • 8
  • 18