4 ms·
Ruby takes this to 100. As much as a I love Ruby, this is valid Ruby, and I can't defend this: puts "This is #{<<HERE.strip} evil" incredibly HERE
by vidarh 2y ago
Ruby takes this to 100. As much as a I love Ruby, this is valid Ruby, and I can't defend this:
puts "This is #{<<HERE.strip} evil"
incredibly
HERE
Just to combine the string interpolation with her concern over Ruby heredocs.
My other favorite evil quirk in Ruby is that whitespace is a valid quote character in Ruby. The string (without the quotes) "% hello " is a quoted string containing "hello" (without the quotes), as "%" in contexts where there is no left operand initiates a quoted string and the next characters indicates the type of quotes. This is great when you do e.g. "%(this is a string)" or "%{this is a string}". It's not so great if you use space (I've never seen that in the wild, so it'd be nice if it was just removed - even irb doesn't handle it correctly)
- jart 2y agohttps://pbs.twimg.com/media/GbEfj6fbQAQRUB7?format=png&name=small https://pbs.twimg.com/media/GbEfj6fbQAQRUB7?format=png&name=... That's so going in the blog post later today.
- vidarh 2y agoHeh. I love Ruby, but, yes, the parser is "interesting", for values of interesting left undefined for its high obscenity content.
- mdaniel 2y agoAnd don't overlook the fact that the bare-world, or its "HERE" friend, are still in an interpolation context, so... puts "hello #{<<onoz.strip} world" recursion is #{<<onoz.strip} recursive onoz onoz puts "that was fun" yields hello recursion is recursive world that was fun and then there's its backtick friend puts "hello #{<<`onoz`.strip} world" date -u onoz coughs up hello Sun Nov 3 17:25:32 UTC 2024 world and for those trying out your percent-space trick, be aware that it only tolerates such a thing in a standalone expression context so puts (% hello )+" world" # or x = % hello # puts x because when I tried it "normally" I got $ /usr/bin/ruby -e 'puts % hello + "world"' -e:1:in `<main>': undefined local variable or method `hello' for main:Object (NameError) $ /usr/bin/ruby -v ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin21] but, at the intersection is "ruby parsing is the 15th circle of hell" ruby -e 'puts (% #{<<FOO.strip} )+ " world" hello FOO '
- vidarh 2y ago> $ /usr/bin/ruby -e 'puts % hello + "world"' Yes, it's roughly limited in use to places where it is not ambiguous whether it would be the start of a quoted string or the modulus operator, and after a method name would be ambiguous. > but, at the intersection is "ruby parsing is the 15th circle of hell" It's surprisingly (not this part, anyway) not that hard. You "just" need to create a forward reference, and keep track of heredocs in your parser, and when you come to the end of a line with heredocs pending, you need to parse them and assign them to the variable references you've created. It is dirty, though, and there are so many dark corners of parsing Ruby. Having written a partial Ruby parser, and being a fan of Wirth-style grammar simplicity while enjoying using Ruby is a dark, horrible place to live in. On the one hand, I find Ruby a great pleasure to use, on the other hand, the parser-writer in me wants to spend eternity screaming into the void in pain.