Nothing surprising there. Let’s replace that 3 with the call that returns 3.
$ cat f2.rb
puts "foo".length?"stuff":"empty"
$ ruby f2.rb
f2.rb:1:in `': undefined method `length?' for "foo":String (NoMethodError)
Did you mean? length
But that parsed as "foo".length? and was looking for a method call because ruby methods can end in ? but couldn’t find the method so returned an error.
Let’s put a space in there so that its the length method again without trying to become length?
And this returned what was expected… but this needed a lot more spaces in a lot more places than the puts 3?"stuff":"empty" that worked in the first call.
I agree! I don’t think 3?”stuff”:”empty” should work at all because I think it’s an insane way to type a ternary :) I’m also very open to admitting that it’s just my own strongly worded opinion.
I think that in most cases, syntactically significant whitespace is a horrible idea - the one exception being that you should have space between operators/identifiers/etc. I don’t care how much, and 4 spaces should have no more special meaning than 1, but I do think that using a space to indicate “this thing is a different thing than the thing before it” is important.
3?"bar":"qux" only has the ternary expression as a valid parsing of ?
foo?"bar":"qux" fails because foo may be a method and foo? is also a valid method identifier.
foo ?"bar":"qux" fails because ?" uses the ? unary operator that makes the next character a string. So ?"bar" becomes the string " followed by what looks to be an identifier.
And so…
? character is a valid part of an identifier (but only at the end of a method name)
?x unary operator to create a String from a character
In Ruby,
foo?a:b
parses differently thanfoo ?a:b
and the first one isn’t parsed a ternary expression.Consider the following code snippets and execution:
Nothing surprising there. Let’s replace that
3
with the call that returns3
.But that parsed as
"foo".length?
and was looking for a method call because ruby methods can end in?
but couldn’t find the method so returned an error.Let’s put a space in there so that its the
length
method again without trying to becomelength?
It’s apparently expecting something with the
"stuff"
. Lets put in more spaces.And this returned what was expected… but this needed a lot more spaces in a lot more places than the
puts 3?"stuff":"empty"
that worked in the first call.Personally, I think that if you’d rather write
foo?a:b
thanfoo ? a : b
, you’re probably insaneBut why would
3?"stuff":"empty"
work andfoo?"stuff":"empty"
not work?Syntactically significant whitespace is a nightmare to deal with.
I agree! I don’t think
3?”stuff”:”empty”
should work at all because I think it’s an insane way to type a ternary :) I’m also very open to admitting that it’s just my own strongly worded opinion.I think that in most cases, syntactically significant whitespace is a horrible idea - the one exception being that you should have space between operators/identifiers/etc. I don’t care how much, and 4 spaces should have no more special meaning than 1, but I do think that using a space to indicate “this thing is a different thing than the thing before it” is important.
Talking with a rubyist:
3?"bar":"qux"
only has the ternary expression as a valid parsing of?
foo?"bar":"qux"
fails becausefoo
may be a method andfoo?
is also a valid method identifier.foo ?"bar":"qux"
fails because?"
uses the?
unary operator that makes the next character a string. So?"bar"
becomes the string"
followed by what looks to be an identifier.And so…
?
character is a valid part of an identifier (but only at the end of a method name)?x
unary operator to create a String from a characterexpr?expr:expr
ternary operatorAnd so…
puts "".empty? ? ?t:?f