View_php

4 Reasons Why Ruby Syntax Is Better Than PHP's

7 Dec 2008 at 10:18pm 21

Having been a Rails developer for a little over a year now and after
completing a few Rails projects successfully, I thought I'd post a set
of reasons why I think Ruby has a cleaner syntax than PHP.

The worst
part of this for me is that PHP can fix a lot of these things and have
a much nicer syntax but in the interests of backwards-compatibility are
fairly tied to the current syntax.

1. Objects vs Functions

As Ruby is a pure OOP language as opposed to PHP's bolted-on functionality, doing things like multiple chained actions are a lot more readable in Ruby. Take for example a case when you have a hash where you want the first 3 alphabetically sorted key values. In PHP you'd do the following:



$foo = array("zulu" => "1", "alpha" => "4", "golf" => "8", "bravo" => "3");

$keys = array_keys($foo);
sort($keys);
$bar = array_slice($keys, 0, 3);


This seems incredibly verbose mainly due to - as Rob points out in the comments - the fact that PHP doesn't return the sorted array from sort. If it did you could do something like this:



$foo = array("zulu" => "1", "alpha" => "4", "golf" => "8", "bravo" => "3");

$bar = array_slice(sort(array_keys($foo)), 0, 3);


But even that seems arse backwords to me, it feels like you're defining what you're doing to the hash before you get anywhere close to the hash and then have parameters after array_keys and sort that aren't immediately (without counting back brackets) related to the slicing action.



Compare this to the ruby equivalent:



foo = {"zulu" => "1", "alpha" => "4", "golf" => "8", "bravo" => "3"}

bar = foo.keys.sort.slice(0,3)


This reads a lot more logically as the information builds from left to right like an English sentence. You could also make it more obvious you're calling methods by using the less Ruby-looking:



bar = foo.keys().sort().slice(0,3)



Or you could make it more ruby-like and use a range in array access style instead of the slice method:



bar = foo.keys.sort[0..2]



2. Hash As The Last Parameter


If you have a method that can take varying named options, Ruby has a very nice syntax where you can use symbols as the keys and it will automatically combined them in to a hash (associative array in PHP terms). Take the example below:



my_object.my_function(1, 2, :sort => "name", :limit => 10)



This can be done in PHP but it takes an extra array keyword and just doesn't look as nice because of the extra parenthesis:



$my_object->my_function(1, 2, array("sort" => "name", "limit" => 10))



Of course named parameters would be even better, but then again I'm not a Python developer...




3. Blocks


Ruby uses blocks (closures, lambdas and other related terms) throughout the language and are very useful for providing specific functionality in a single place that you wouldn't want to define a function for. For example, take the point of providing a custom sort option for an array of objects where you want to sort them by the object's price property. In PHP you'd do it like this:



function sort_my_objects_by_price($a, $b)

{
if ($a->price == $b->price) {
return 0;
}
return ($a->price > $b->price) ? +1 : -1;
}

usort($my_array, "sort_my_objects_by_price");


In Rails you'd do it like this (using the much shorter comparison operator doesn't help make this fair, but still):



my_array.sort do |a, b|

a.price <=> b.price
end


That's much more readable. You can do something similar in PHP with create_function looking like this:



usort($my_array, create_function('$a, $b', 'if ($a->price == $b->price) {

return 0; } return ($a->price > $b->price) ? +1 : -1;'));


(Thanks to Rob for the correction - reminder to self - don't post unless fully awake)

However, that's nowhere close to being readable and looks very unusual to any professional PHP developer. It's effectively "eval" which as everyone knows should really be spelt *evil*. Editors won't syntax highlight the code (even though Google's Javascript Syntax Highlighter does above) so it's not obvious if there are any simple errors.



Another time to use blocks is for content of helpers in a Rails-like situation or doing something to each element of a returned function.



Accounts.active do |account|

account.notify_downtime
end


Of course in Rails for the above there's an even simpler way of doing it by using symbol#to_proc:



Accounts.active(&:notify_downtime)




4. Monkeypatching


This is something that creates a lot of debate in the Rails/Ruby communities anyway. For the PHP developers reading this, Monkeypatching is the act of changing base or built in classes such as array or string to add new functionality or change they way they work. It obviously then has the potential to create havoc in understanding why something is happening.



There are slightly better ways of doing it than just opening a class and adding your own function. For example, say you want to add a vat() method to all Fixnums to calculate VAT at the (current) rate of 15%. You could do it like this:



class Fixnum

def vat
self * 0.15
end
end


Or you could create your own module and include it in Fixnum using something like the following:



module MyCompanyName

module FinanceFunctions
def vat
self * 0.15
end
end
end

Fixnum.send(:include, MyCompanyName::FinanceFunctions)


This does the same thing but it means that the functions are separated for testing purposes, can be included in multiple classes without code duplication and it makes it a lot more obvious that you're doing it.



This example is fairly trivial but the point remains - considering and being aware of the risks, Monkeypatching gives you flexibility.




Your Thoughts


So, those are the top 4 reasons I prefer Ruby syntax to PHP syntax. What do you think? Am I missing some more obvious reason why Ruby is better than PHP (from a syntax point of view)? Can anyone provide an example of somewhere they think PHP syntax is actually better? Let me know in the comments.

Other articles you may like:

21 Comments so far

2c9cc7a7fc210d70ab0b0bab3172b845

Rob wrote on 08 December 2008 at 08:30

Hey Andy, interesting post, however I get the feeling you didn't test your snippets. You arguments still stand (more in some cases) but quite a lot of PHP examples are just plain wrong.

1. PHP's sort works in place and returns boolean.
3. create_function accepts a string representing the parameter list.

To be honest, I think it would be better if PHP did work as you described. Unfortunately, it's even worse.

5cb7a05b6de4a6655319db9333be429c

Andy Jeffries wrote on 08 December 2008 at 08:42

@Rob: indeed I didn't - the problem with writing a blog post late at night! Thanks for the corrections, I've amended the article.

P.S. what was your second point? ;-)

2c9cc7a7fc210d70ab0b0bab3172b845

Rob wrote on 08 December 2008 at 08:51

Sorry, I wasn't clear. The numbers correspond to your examples.

8bba46dba9043c254e6eef1aa664e6f0

EllisGL wrote on 08 December 2008 at 13:37

It's not "better" or "worse". You just prefer it over the PHP way.

B6116ac3c4b5835c6745570ea73a85c1

Charles wrote on 09 December 2008 at 02:18

Thankfully, PHP 5.3 has closures, meaning this becomes legal:


usort($array, function($a, $b) { ... });


Still not quite as elegant due to the requirement of the function keyword, but it works.

E7b27313f932222f22beaa3686746bd3

Piccolo Principe wrote on 09 December 2008 at 14:31

"As Ruby is a pure OOP language"
Maybe I could suggest a reading:
http://en.wikipedia.org/wiki/Law_of_Demeter
example #1 is a particular case where methods returns the same interface, but the "English sentence" calling of methods is not so powerful as it seems (a object returning another object returning an iterator returning an array...);
However, in the Standard Php Library:
http://www.php.net/~helly/php/ext/spl/classArrayObject.html
that is distributed with the php core, you can do a $array->asort() or $array->ksort(), etc; closure can be substituted in php5 with a Strategy pattern, and so on. That's not so useful.
The point is design and architecture are mandatory for a scalable and healthy application, and that conflicts with super-short syntax and monkey patching (very horrible.. see Open/Closed Principle).
Speaking in php terms, its syntax is inherited from C and Perl. It means that programmers with a Unix background often learn quickly a basic use of php.

5170ca260dbd2cdfd5a887a4dba7636f

Jeremy Weiskotten wrote on 09 December 2008 at 14:38

@Piccolo I don't think the Law of Demeter applies in this case. Operating on an array does not introduce a dependency. LoD does not say you can't call methods on an object.

AFAIK Ruby is one of very few "pure" OO languages. Everything in Ruby is an object.

And, IMO, PHP syntax is horrid. That doesn't mean PHP isn't sometimes the right tool for the job -- it often is. But I think anyone would be hard-pressed to come up with an argument that PHP syntax is superior, whether it's purely subjective or not.

135dc4655009942421d5def8c6d153b4

Sean Nieuwoudt wrote on 10 December 2008 at 10:12

PHP does what its intended for well, even though the syntax might not be all that great.

I stand by my opinion of picking a language that does the job at hand and stop worrying about the "look" or "feel" of it.

6ec940e957647cafede831c5943bea84

Ahad Bokhari wrote on 12 December 2008 at 15:25

The fact that Rails syntax is alot more readable(at least to me) is what draws me to it.

Andy thanks for guiding me the right way => The Rails way!! Rails is def upping there speed and i'm glad i boarded the train!!!

Check this article: <a href="http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html&quot;&gt;7 reasons I switched back to PHP after 2 years on Rails</a> for a good laugh....

C3c5bd5e8bf188dad0375dfb85459ff7

Anoop John wrote on 21 December 2008 at 22:35

Hi Andy,

I am a PHP Developer and I have been using gphpedit for PHP development. I had once tried to contact you via the andy@gphpedit.org site regarding some bugs that I wanted to send patches for. Are you still maintaining the gphpedit package? If not then can you please point me to the person who is maintaining this package. BTW if you are not maintaining it, then what is the editor that you use for PHP development :-)

You can please delete this comment. I commented because I could not find a contact page on this site.

290f7d02e06609ab1a2be94e7a487b71

Ron wrote on 28 December 2008 at 00:21

I don't trust any language that doesn't terminate a line with a semicolon ;

Ruby reminds me of VB, and that's not a good thing. Same issue I have with Python. Not C like at all.

6ec940e957647cafede831c5943bea84

Ahad wrote on 02 January 2009 at 13:02

MERB + RAILS = Rails 3.0 | Can you imagine Andy?

A7acb8d603b49f4c6143b5379488ed39

Paul Ardeleanu wrote on 27 January 2009 at 15:22

Glad to see you are walking the right path! :)

5cb7a05b6de4a6655319db9333be429c

Andy Jeffries wrote on 28 January 2009 at 08:35

@Ahad: I know, I'm looking forward to that (but in two minds as to whether to look in to Merb now to see what's coming, or leave it until Rails 3.0 when I'll look in to what's new in Rails 3 anyway)...

@Paul Ardeleanu: I'm late to the party but at least I came. I've been using it for just over a year now and it's just awesome! Every time I work on something in it I find some new cool awesome trick.

A7acb8d603b49f4c6143b5379488ed39

Paul Ardeleanu wrote on 14 February 2009 at 18:02

Did you try engines in Rails 2.3 (alpha 1 at the moment)?

5cb7a05b6de4a6655319db9333be429c

Andy Jeffries wrote on 16 February 2009 at 11:28

No. I'm running 2.3RC1, but haven't had a need for Engines yet.

I did wish for the functionality (and saw it was available as a gem/plugin when I first looked) when I rewrote this site to be Rails based as my friend used my previous Symfony version for his site (so we could share the code again). But didn't have time to take it any further.

I'm looking forward to the improved nested form support though - I've got a feature on a site that is marked for refactoring when 2.3 is released (I feel that I can't release a commercial site on an RC of the framework).

D5d5f290fe371b96716a80402a535314

Ron wrote on 17 October 2009 at 18:55

Well in the end Perl 6 wins over both! ;)

B48def645758b95537d4424c84d1a9ff

Dan wrote on 04 November 2009 at 15:44

For me, there's plenty of more reasons to chose ruby over PHP in almost any context. PHP quickly becomes a horrible mess, while ruby can be written in a very concise way that doesn't get in your way.

5cb7a05b6de4a6655319db9333be429c

Andy Jeffries wrote on 04 November 2009 at 15:47

I agree. Having just launched a major Rails site, the ease with which I've been able to jump in to fix teething problems, quickly and reliably has been not possible previously with PHP projects. In both my previous projects and this one I've not been a sole developer, so it's definitely not just my code has better :-)

The code has been much readable and concise than would have been possible with PHP.

5cb7a05b6de4a6655319db9333be429c

Andy Jeffries wrote on 12 November 2009 at 13:57

By the way, the code example I gave in Section 2 got slightly nicer still in Rails 1.9:

my_object.my_function(1, 2, sort:"name", limit:10)

Cb68dc59f9f2694a3c82c37ce1b12687

Ted Pennings wrote on 20 July 2010 at 02:48

while I hate PHP, you can actually use closures in PHP too

usort($arr, function($a, $b) { return $a > $b; } );

does the same thing as your 10 lines of bad PHP.

Click here to have your say...


You can use <b>+</b>, <i>+</i> and <blockquote>+</blockquote>