Differences between PHP Arrays and Ruby Hashes

We've looked at the diferences between Ruby and PHP arrays before. Now lets compare PHP arrays and Ruby hashes. They should be similar as all PHP arrays are implemented as hashes. There is however a cruicial difference that can trip you up if you are switching from one language to another.

 

Referencing an index that hasn't been set is an error in PHP, but not in Ruby.

In PHP, retreiving a value for an index that you haven't used is a warning. Although warnings can be turned off it is best practice to develop with them turned on.

<?php

$a['key1'] = 'value1';
$a['key2'] = 'value2';

print $a['key5'];
/*
lang@virtualbox1:~/$ php hash.php
PHP Notice: Undefined index: key5 in /home/lang/hash.php on line 6
*/
?>

In Ruby you can set a default value for all keys that have not set a value. By default this value is nil.

a = Hash.new

a['key1'] = 'value1'
a['key2'] = 'value2'

puts a['key5']
=begin
lang@virtualbox1:~/$ ruby hash.rb
nil
=end

 

Ruby hashes are unordered (up to version 1.8). PHP arrays have an internal order seperate from their index.

When you loop through a PHP array, the values will be returned in the order they were added.

<?php

$a['key1'] = 'one';
$a['key0'] = 'zero';

foreach($a as $value) {
        print $value . "\n";
}
/*
lang@virtualbox1:~/$ php hash.php
one
zero
*/

?>

In Ruby 1.8 hashes are unordered, they could be retreived in any order that ruby decides is best. Ruby 1.9 changes this so that it works in the same way as the PHP example above.

a = Hash.new

a['key1'] = 'one'
a['key0'] = 'zero'

a.each_value do |value|
        puts value
end
=begin
lang@virtualbox1:~/$ ruby hash.rb
zero
one
=end

Is there anything that has been missed? Add a comment below.

Posted by Lang Sharpe
Sat, 19 Mar 2011 11:03:00 GMT

Major differences between PHP and Ruby Arrays

PHP has a single array type, where as Ruby has Array and Hash, which covers the same functionality. In this article i'll go though the three major logical differences between PHPs array type and Rubys Array classs. We compare PHP arrays and Ruby Hashes in seperate post.

Firstly,

PHP arrays have an internal order seperate from their index.

Lets look at a simple example. In php the order you insert values into an array
determines the order that php will return them using foreach

<?php

$a[1] = 'one';
$a[0] = 'zero';

foreach($a as $value) {
        print $value . "\n";
}

/*
lang@virtualbox1:~/arrays$ php array.php
one
zero
*/
?>

Ruby on the other hand uses the key or index of the array to determine the order, regardless of order in which the values are inserted.

a = Array.new

a[1] = 'one'
a[0] = 'zero'

a.each do |value|
        puts value
end
=begin
lang@virtualbox1:~/arrays$ ruby array.rb
zero
one
=end

Secondly,

Ruby arrays always start at 0 and end at the highest index. PHP arrays only contain the keys that have been entered.

In the example below, PHP will output the two array values that are set.

<?php

$a[2] = 'two';
$a[4] = 'four';

foreach($a as $value) {
        print $value . "\n";
}

/*
lang@virtualbox1:~/arrays$ php array.php
two
four
*/
?>

In the ruby example, not only are the two values output, but an attempt is made to get the value from every index between 0 and the highest index set.

a = Array.new

a[2] = 'two'
a[4] = 'four'

a.each do |value|
        puts value
end
=begin
lang@virtualbox1:~/arrays$ ruby array.rb
nil
nil
two
nil
four
=end

This leads to another difference…

Referencing an array index that hasn't been set is an error in PHP, but not in Ruby.

The following code produces a PHP notice. Notices are a low severity error, and are usually turned off on production servers. However it is considered good practice to develop with notices turned on.

<?php

$a[2] = 'two';
$a[4] = 'four';

print $a[5];

/*
lang@virtualbox1:~/arrays$ php array.php
PHP Notice: Undefined offset: 5 in /home/lang/arrays/array.php on line 6
*/
?>

Ruby on the other hand does not consider this an error. It will return the nil value which is 'kind of' like PHPs null.

a = Array.new

a[2] = 'two'
a[4] = 'four'

puts a[5]
=begin
lang@virtualbox1:~/arrays$ ruby array3.rb
nil
=end

So what are your experiences switching between PHP and Ruby. Let me know in the comments below.

Posted by Lang Sharpe
Thu, 10 Mar 2011 16:45:00 GMT

The best feature of VIM not in IDE's

'Insertion mode keyword completion'.

Ctrl-P and Ctrl-N in insert mode to search through the text to try and complete whatever variable name you are typing. I've never seen this in any other IDE and I really miss it. Code completion in IDE's just isn't the same.

Posted by Lang Sharpe
Mon, 11 Oct 2010 18:00:57 GMT

Speak the truth 1

Improper uses of Booleans causes headaches for people who are reviewing your code. Lets take a look at some good, and not so good uses.

Don't be negative

if $notLoggedIn then

Looks simple and readable right? Wrong. It's one step away from being misused.

if ! $notLoggedin then

Not not logged in. Double negatives are a gotcha in language and coding and should be avoided. Fortunately the solution is an easy one. Remove the negative prefix (such as not, doNot, dont) from the variable name.

if $loggedIn then

if ! $loggedIn then

Hide Literals

if $hidden == false then

Is it really necessary to compare the variable to false?

Imagine this conversation. You are at Subway and they ask you

"Would you like your sandwich toasted?"

Would you reply with

"Toasted equals false"
  Or
"Not Toasted"

Avoid comparing with a literal true or false. The correct way to express this is :-

if ! $hidden then

A Boolean Flag?

if $reportFlag then

$reportFlag is a little vague. In this case it is determining if an object is included in a report. So if $reportFlag is true, does that mean that the object is included or excluded? If you have to ask yourself the question then you have already failed and need to rethink what this variable should be called.

if $report then

This is okay as long we are using the word 'report' as a verb. "If we report this then" is how you would read this. Some people may not be able to make that leap so if you want to be more precise you could make it :-

if $includeInReport then

Summary

So to sum up, these three things will go a long way to making your code readable.

  • Remove the negative prefix (such as not, doNot, dont) from variable names.
  • Avoid comparing with a literal true or false.
  • Avoid vague terms like flag for Boolean values.

Consider these ideas when choosing

  • Variable names
  • Object properties
  • Database field names
  • Method or function parameter names

Anything Else?

Is there something i've missed? A hole you could drive a double-decker bus through? Leave a comment below.

Posted by Lang Sharpe
Mon, 06 Sep 2010 12:00:00 GMT

Ctrl-A Delete

Usually a last resort. Often the best thing to do.

Posted by Lang Sharpe
Wed, 04 Aug 2010 16:52:00 GMT

Switching from web to desktop application development

Switching jobs and making a career change is a big challenge. New problem domains to learn, new working relationships to build, new brand of instant coffee to get used to. For a programmer one of the more interesting changes can be moving from working on web applications to desktop applications. Here are a few points that i've picked up having made the plunge a few months ago.

  • Control of environment. As a web programmer you have a lot of control of the environment your application runs in. Browser issues aside, once a HTTP request hits your servers you have complete control over what happens next. A desktop application has little control over where it is being run, what software is installed with it etc.
  • Managing performance. A desktop application performing poorly can be a nightmare to diagnose. The characteristics of the users machine and currently running processes are completly foreign. If your web app is running slowly you not only have the program available but intimate knowledge of the hardware and architecture it is running on. You can make tradeoffs on the servers that your users may not be willing to do for your desktop application.
  • 24/7 operations. Most web developers will not only have to create the application, but support it as well. These problems that occur on live systems are usually given high priority pushing more long term work to the back.

I had no idea how narrow my knowledge was. I'd be interested to hear your thoughts. Have you made the switch from web to desktop, or in the other direction?

Posted by Lang Sharpe
Mon, 26 Jul 2010 21:20:53 GMT

Creating a static class variable in ruby

One of the patterns I (over)use in php is having a class with only static variables and static functions. To do this in ruby isn't as straight forward as it could be, so here is how to do it.

class StaticKlass

    # ruby class variables are prefixed with "@@" .
    @@variable = nil

    # If you want to provide getters and setters you cant use the attr_accessor
    # keyword, you have to create them manually. By adding the class name to
    # the method definition, we are indicating that this is a method on the
    # class, not in instances of this class
    def StaticKlass.variable= (x)
        @@variable = x
    end

    # the getter is defined to return the class variable when called
    def StaticKlass.variable
        return @@variable
    end

end

Posted by Lang Sharpe
Tue, 08 Jun 2010 19:00:52 GMT

WTF - Scheduled Reports

Working on scheduled reporting systems, you expect to see the same concepts. What format wiil we send the report in? How will it be delivered? I opened the “scheduled report” table to see how this particular system had been implemented. I couldn’t immediately find which column i was looking for. In fact the only one that looked like it might be useful was something called deliv_method.

deliv_method
206
774
206
206

Ok, so we’ve got a numeric list of delivery methods. Nothing too unusual about that. I just need to find the list either in the database or codebase. But where do we store the format of the report? I worked my way through the report scheduler code until i found this.

$delivMeth = ($row[‘DELIV_METHOD’] >> 8);
$myFormat = ($row[‘DELIV_METHOD’] & 0xFF);

Are those bitwise operators? And even a literal hexadecimal number? The only place i’ve ever seen a bitwise operator is when setting the error reporting level. I’ve looked at this a few times and am still not sure i correctly understand it.

The answer eventually revealed itself.

$a = array(
0x0104 => "Email HTML",
0x0204 => "Email HTML Attachment",
0x0284 => "Email HTML Zipped attach",
0x0201 => "Email PDF",
0x0203 => "Email TSV delim",
0x0283 => "Email TSV delim zipped",
0x0203 => "Email CSV delim",
0x0283 => "Email CSV delim zipped",
0x0304 => "FTP HTML",
0x0301 => "FTP PDF",
0x0303 => "FTP TSV delim",
0x0303 => "FTP CSV delim",
);

Pretty clever you have to admit! Unfortunately it can lead to same rather ugly code.

if ((($('#INPUT\[DELIVERY_METHOD\]').val() & 0xFF00) >> 8) != 0x03){

Posted by Lang Sharpe
Tue, 25 May 2010 07:00:02 GMT

Help eliminate bad code

The Bad Code Offsets project is an attempt to get programmers to put money into open source software. We may not be able to change the bad code we have written. Instead we can buy an offset that goes towards creating more good code.

Bad code lives on well past the time we inflicted those bad lines into the global code base. Applications continue to live their lives serving businesses, consumers and the global community at large. Bad code weakens the utility delivered by these applications causing business loss, user dissatisfaction, accidents, disasters and, in general, sucks limited resources towards responding to the after effects of bad code rather than toward the common good.

They have just made a $500 grant to the GPSd project, which aims to shield developers from the idiosyncracies of integrating each GPS device available.

How often do you use open source software. How often have you contributed, either by submitting code or donating money? My gut feeling is that at least 95% of developers haven't done either. The 10 USD I donated will be going to the Apache software foundation. The apache webserver has been at the base of nearly every project I've worked on and will be for a long time to come.

Posted by Lang Sharpe
Wed, 27 Jan 2010 08:00:44 GMT

grepWin - Grep for windows

grep is an often used tool on linux. It's job is very simple, to find a string (or regular expression) in a group of files.

grepWin is a gui version and is a lifesaver if you have to use windows as part of your development environment. The best bits are

  • Integrates with windows explorer. Search any folder by right clicking on it.
  • Results behave just like a windows explorer folder. Right click on the files to edit from the results panel.
  • Regular expression support. A feature compared to windows built in search.
  • Search and replace. The tool goes further than grep and will do a search and replace over many files.
grepWin Screenshot

Posted by Lang Sharpe
Wed, 06 Jan 2010 14:00:00 GMT