After my previous diatribe, I had no option but do some further research, just as a sanity check.
So, along comes Ruby.
(from wikipedia)
According to the Ruby FAQ,[22] “If you like Perl, you will like Ruby and be right at home with its syntax. If you like Smalltalk, you will like Ruby and be right at home with its semantics. If you like Python, you may or may not be put off by the huge difference in design philosophy between Python and Ruby/Perl.”
Sounds good actually!
ashpool:~# apt-get install ruby
ashpool:~# cat >test.rb
#!/usr/bin/ruby
print "hello world\";
^D
ashpool:~# chmod 755 ./test.rb
ashpool:~# ./test.rb
hello world
Hmm, that was actually pleasant! And I used a semicolon successfully!
So, then I do some further reading:
(from wikipedia)
Boolean evaluation of non-boolean data is strict: 0, “” and [] are all evaluated to true. In C, the expression 0 ? 1 : 0 evaluates to 0 (i.e. false). In Ruby, however, it yields 1, as all numbers evaluate to true; only nil and false evaluate to false.
What? You just broke binary! A fundamental computing principle. And also, by the way, the “principle of least astonishment”. Yes, I understand that it’s not supposed to be entirely true according to Matsumoto, but quite frankly I’m astonished.
To soften the blow:
A corollary to this rule is that Ruby methods by convention — for example, regular-expression searches — return numbers, strings, lists, or other non-false values on success, but nil on failure.
That’s fine, I don’t mind your convention, and it makes neat sense, since zero isn’t always a good indication of failure and a nil, tells me something more than zero.
But for fucks sake.
0 is false, 1 is true. And it doesn’t matter what the radix is… I see no reason to mess with that basic computing principle for the sake of a convention involving nil.
Once again — please, Mr. Interpreter, get out of my way, and let me get on with the job of programming. I’ll decide what is true and false, thank you very much. And 1 is true and 0 is false.
So, let’s try something simple. A loop!
cat >./test.rg
#!/usr/bin/ruby
for i in (1..2)
print "hello world\n";
end
ashpool:~# ./test.rb
hello world
hello world
That wasn’t so bad. The loop construct seems a bit simple (or maybe just nonclassical) but can be neatly used to iterate data structures such as one would expect from a dynamically typed language.
But srsly — “end” ?
I feel like I’m back in Pascal hell already. But at least the whitespace wasn’t significant. And “end” at least made things quite clear.
Being able to use a semicolon (without complaint) was also quite nice, and refreshing, for a change. But honestly, would it really have killed the language to allow {} as shortcuts ?
Aaah, wait, I see the problem here…
{} is also syntax for blocks, but only when passed to a method OUTSIDE the arguments parens.
When you invoke methods without parens, ruby looks at where you put the commas to figure out where the arguments end (where the parens would have been, had you typed them)
example:
1.upto(2) { puts 'hello' } # it's a block
1.upto 2 { puts 'hello' } # syntax error, ruby can't figure out where the function args end
1.upto 2, { puts 'hello' } # the comma means "argument", so ruby sees it as a hash - this won't work because puts 'hello' isn't a valid hash
Holy shit.
This is why we have “()” and family in a decent language. Look! Here are the args — “()”. Here is the code block — “{}”. Here’s an array — “[]”. Here’s the end of the statement — “;” Zero ambiguity.
It appears that every time someone invents a new language to address the supposed inadequacies in other languages something goes awry.
I’m still willing to give Ruby a bit more of a go, since there’s seems more sensibility and flexibility than them Python dragons enforce.
For example, my simple little string “acid test”.
ashpool:~# cat >test.rb
#!/usr/bin/ruby
test="123";
test[1]="b";
print test;
^D
ashpool:~# ./test.rb
1b3
I’m going to have a tough time dealing with the stupidity of 0 and 1 though…
Perhaps I’m too much of a traditionalist, and and old fart, but quite frankly, I’d rather be coding Perl, PHP, or C.
Eh, on python’s technical merits I’ll still fight the good fight, but at Ruby I draw the line. We can commence the ridicule of the language on the balcony later today 😉
Programming languages is a favorite topic of mine.
I have to say, other than your comments about Python namespaces in the previous post, the gripes with Python and Ruby you’ve listed so far appear to be largely irrelevant to the language’s suitability for solving problems. More important design aspects can be described. Consider the following attributes:
* Generality and orthogonality
* Typing, binding, scope
* Supported control and data structures
* Available mechanisms for abstraction
* Implementations and tools
* Standard libraries and documentation
* Portability and platforms supported
* Performance
Unless your objective is merely be to write about subjective syntactic preferences, I would be keen to see some commentary from you along these lines.
Ahh the joys of Ruby. Have you discovered all the cases where it will silently accept conversion data without throwing any exception?
irb(main):004:0> Time.parse(“Your mom”)
=> Mon Feb 28 12:56:25 +0200 2011
irb(main):005:0> “Your mom”.to_i
=> 0
Fun times
Oh yes and
irb(main):006:0> “abc”[1]
=> 98
Wut??
Did you do this one as well?
irb(main):001:0> x = 0
irb(main):002:0> if x
irb(main):003:1> puts “ok”
irb(main):004:1> end
ok
Why is integer zero equitable to true?
Haven’t tried all of those corner cases yet. But in keeping with Simeon’s suggestion, I’m building a more fully fledged evaluation. To be published Real Soon ™.