Confused about andand

Hello,

I'm reverse engineering some code I inherited, and having a little
trouble understanding andand. I know that

  a.andand(b)

  is equivalent to

  a && a.b

and yet I'm still having trouble understanding:

id = step.search("property[name=id]").first.andand["value"]

I would like to rewrite it using the "&&" notation, to have as a comment
in the code.

If you could write it out for me, it would help a lot. Thanks!

···

--
Posted via http://www.ruby-forum.com/.

and yet I'm still having trouble understanding:

id = step.search("property[name=id]").first.andand["value"]

I would like to rewrite it using the "&&" notation, to have as a comment
in the code.

If you could write it out for me, it would help a lot. Thanks!

I'm guessing that step.search() may return an empty list.

So .first will return

  1) the first item in the list
or
  2) nil if the list is empty

In the first case calling ["value"] will work because first returned something.
In the second case calling ["value"] will fail because first is nil.

The 'solution' is to use 'andand' to hide the 'failure' in the second case and just
return nil.

Here is a rewrite that might make this clearer:

first_item = step.search("property[name=id]").first

if first_item
  id = first_item["value"]
else
  id = nil
end

Using the && operator that looks like:

first_item = step.search("property[name=id]").first

id = first_item && first_item["value"]

The andand method is just a tidy way of wrapping up this logic. You really need the temporary variable to avoid repeating the complex expression when using the && operator (see how first_item is repeated?) and it is syntactically complex to do that for complicated expressions in a 'one-liner':

id = step.search("property[name=id]").first && step.search("property[name=id]").first["value"]

with a local variable to avoid re-evaluating the complex expression:

id = (f = step.search("property[name=id]").first) && f["value"]

It gets worse if you need additional steps:

id = (s = (f = step.search("property[name=id]").first) && f["value"]) && s.["another_value"])

vs

id = step.search("property[name=id]").first.andand["value"].andand["another_value"]

Gary Wright

···

On Jan 24, 2011, at 3:57 PM, Dan Thomas wrote: