tags:

views:

91

answers:

3
+3  Q: 

ruby edge cases

ruby has some edge cases which is hard to explain because parsing brings some interesting issues. Here I am listing two of them. If you know of more then add to the list.

def foo
  5
end

# this one works
if (tmp = foo)
  puts tmp.to_s
end

# However if you attempt to squeeze the above
# three lines into one line then code will fail
# take a look at this one. I am naming tmp2 to 
# avoid any side effect

# Error: undefined local variable or method ‘tmp2’ for main:Object
puts tmp2.to_s if (tmp2 = foo)

Here is another one.

def x
  4
end

def y
  x = 1 if false 
  x + 2
end

# Error: undefined method `+' for nil:NilClass
puts y

However if you comment out the line x = 1 if false then code will work fine.

Please add if you know of more edge cases.

+6  A: 

Program bugs are not edge cases


Hmm. In your first example, you assign 5 to tmp, thereby defining the tmp symbol, and then discover that class Fixnum does in fact respond to to_s. But in the first example failure case you try dotting into an undefined symbol ... it's a one-pass interpreter ... and the statement can't be parsed.

Not exactly an "edge case", and I have to wonder if you thought you were comparing tmp and foo.

In the second case, you create a local variable x, but leave it nil because of the if false, and then naturally discover that nil doesn't have a + method. If you comment out the line, the method x is visible and gets called.

That's called lexical scope, not "an edge case".

DigitalRoss
In the first case the edge case was supposed to be that `if exp1 then exp2 end` behaves differently than `exp2 if exp1` if exp1 creates a new local variable. In the second case the edge case was supposed to be that x gets created at all. Note that the line does not get parsed as `x = (1 if false)`, it gets parsed as `(x = 1) if false` so one might wonder why an assignment that never executes introduces a new variable. The answer is of course that such things are decided at parse-time, not run-time, but I'd still say those qualify as edge cases.
sepp2k
-1 for the heading and rudeness.
Andrew Grimm
+5  A: 

In your first example tmp2 is not assigned until it reaches the if statement.

Your second example is not unexpected. Even though x is never assigned it informs the interpreter that you are talking about variable x not function x in the next line. Ruby tries to be pretty loose when determining the context of a name but it will take clues where available. It helps to be specific, for instance:

def y
  x = 1 if false
  x() + 2
end
Corban Brook
I know it helps to be specific. In the first pass my code failed. And then I fixed it by not having another variable with the same name to avoid any conflict. But it raised a flag and I thought it would qualify as an edge case and hopefully would help teach others that in ruby parsers play a role in making or breaking your code.
Neeraj Singh