I don’t like the Ruby 1.9 hash syntax
logicalfriday.com
logicalfriday.com
This really is just, "I am not used to this syntax, so it looks weird to me." It's the same argument some people make against calling methods without parentheses in Ruby. If you're the sort of person who writes "self.houses().map(){|house| house.sale_price()}.sort()", then I guess at least you're being consistent. If not, don't be that guy.
More philosophically, Ruby is a TIMTOWTDI language. There are five different and largely interchangeable ways to create a Proc, half the core library methods are aliases for other methods, several keywords are just slight variations on each other for no purpose other than to give you options, you can take or leave parentheses, etc. The new hash syntax is just one more example of this ethos. If this embarrassment of ways to write any given program bothers you (and you're certainly in good company if it does), you'd probably be more at home with Python. (I don't mean to tell anyone their business, I'm just saying, "only one way to do it" is the Python philosophy.)
I much prefer Python's way of doing things, () is the no-argument call, and without parens is the actual callable object. It emphasizes that functions really _are_ first class values that can be passed around, instead of having to use some special-case syntax to get at the callable.
I'll add the ()'s to intra-class method calls, though; the ambiguity between variable references and funcall expressions bothers the hell out of me, too.
Optional parens are a net win.
^ I realize this can also be dangerous and is the same reason '!' is encouraged as an annotation for methods which have significant side effects.
By the way, I'm pouring over the source for Nancy, a Sinatra inspired micro framework in C# and I see where extension methods and implicit conversion operators are helpful in a DSL.
Other languages have been moving in this direction, too. Objective-C has dot notation, C# lets you define getters and setters, Python has the @property decorator, Scala has special "magic" methods and quirky syntax rules to make this work, etc. All of these serve the same purpose as Ruby's optional parentheses: To make simple method calls less inherently "heavy".
For instance, a few years ago, a summer internship project was to build a native debugger for OS X in pure Ruby, and to help with that, I wrote a chunk of X86 assembly as a Ruby DSL:
I think the real answer is what I said: It makes Ruby's syntax lighter and more flexible so the pony could get more mileage out of its one trick (pure OO), and the convenience of writing DSLs just falls out of that.
BTW, that DSL is an awesome hack.
Symbols always start with a ':'. Creating a symbol from 'foo:' is quite foreign to me (as a 1.8.x user) - ':foo :' [replacing hash rocket with a colon] or similar I would have no complaints about.
{ :test => 1 } == { test: 1 }
is true, but the expression
{ :test => 1 } == { test : 1 }
results in a syntax error. In other words
test:
is almost like a preprocessor directive for
:test =>
which is a strange expansion to have by default in a language.
Just my experience, but I have about a decade of professional Python experience and all of 8 months of professional Ruby experience, and while the rocket syntax drives me nuts in PHP, I actually prefer it in Ruby to the 1.9 syntax.
> I'm just saying, "only one way to do it" is the Python philosophy
Well, there is a lot of effort put into not duplicating functionality in libraries and whatnot, but the actual mantra is:
> There should be one-- and preferably only one --obvious way to do it.
That just means if you need to accomplish a basic task, there should be one obvious solution, it doesn't mean there can't be more than one way to do it.
That's how I've always read it, anyway.
They might be useful as separators sometimes, but why are the absolutely required? They seem like noise. Anyway... I'll stick with hashrockets because the colon at the end is just confusing.
{
foo: capitalize bar,
baz: sanitize quux
}
Without the punctuation, it would be very ambiguous: { foo capitalize bar baz sanitize quux } { :foo => rand 40 }
It requires parens. So Ruby seems to enforce some limit where it's too ambiguous. person.setFirstName(first, lastName: last)
So, introducing it into Ruby 1.9 gave MacRuby the ability of hooking into valid ruby syntax to do its special thing.As a wild speculation, it may also be used for named parameters, should they ever be introduced in Ruby.
Personally, i like it for exactly that case. I do not like it as a generic hash syntax for another reason: its easy to align the =>, but its hard to align the:.
{foo: :bar} just feels weird.
It's not a world-ending issue - certainly not enough to make an effective difference in practical usage - but it's enough of a visual collision that it rubs me the wrong way.
foo: :bar,
baz: :quux,
wub: :bozo
(This is, admittedly, a very subjective complaint. We could start calling this new double-colon syntax collision "Paamayim Nekudotayim".)If you are unfamiliar with Ruby symbols to begin with then it's tough on the brain because there is no discernible pattern.
{ :hash => :rocket }
!As an historical note, here are the message (and matz’s response) where I made a proposal for the new syntax, back in 2002. It includes rationals.
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/...
Matz’s response : http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/...
node.js killed my dog. CoffeeScript gives you diarrhea. a time-traveling Scala user killed JFK. using Erlang is an unforgivable sin.