Fueling the Web

PHP vs. Ruby: Abbreviated Ternaries


One of the cool things about coding is that there is usually more than one way to accomplish the same thing. While I prefer developing in PHP, I've been doing more development in Ruby lately, and it's fun to see both similarities and differences in the two languages. And likewise, it's interesting to see what things I like better in Ruby and what things I dislike in Ruby.

In my experiences with both PHP and Ruby, I'd like to share some similarities and differences as well as show what I learn from one language that I can apply in the other.

Recently, I had a Rails model that needed a method to return the result of a database query. This was a special case where a relationship would not work.

Accomplishing this is easy enough. I could do something like this:

class Car
  def driver
    Driver.first()
  end
end

In this scenario, I'm just returning the first record in the drivers table when calling the driver method.

Here's the problem:

class Car
  def driver
    Driver.first()
  end
end

car = Car.new
puts "#{car.driver.first_name} #{car.driver.last_name}"

In this example, the driver method is hit twice and since the query is not stored anywhere, the same database query is called twice. It's inefficient to run the same query multiple times. Instead, we can do something like this:

class Car
  def driver
    @driver || @driver = Driver.first()
  end
end

Now the driver method will return the value of @driver if it's a truthy value; otherwise, @driver will be set to the result of our query before being returned. This means that all future calls to the driver method will return the previously stored value instead of hitting the database again. You could also use a full ternary statement, but this abbreviated expression serves our purposes.

Now, on to the PHP variation of this scenario. I've done something like the following many times:

<?php

class Car {

  private $driver;

  public function getDriver() {
    if (is_null($this->driver)) {
      $this->driver = Driver::first();
    }

    return $this->driver;
  }

}

That's certainly not bad. I'm explicitly checking if $driver is null and then setting the value prior to returning. However, I think you'd agree that the Ruby example is much shorter and simpler.

So, to shorten this up, we can do the following:

<?php

class Car {

  private $driver;

  public function getDriver() {
    return $this->driver ?: $this->driver = Driver::first();
  }

}

We still explicitly set our $driver variable to private or protected, but our getDriver method is now one line like the Ruby version. Again, you can use a full ternary here if need be, but we're just returning the value of $driver if it's truthy; otherwise, we're setting the value and returning it.

One interesting thing about this PHP variation is the ability to set a variable in the last part of this abbreviated ternary. I knew you could use ?: to return the first value if it's truthy or return the second value, but I hadn't thought to also set a variable in the second part of that statement. Now, depending on how long your expression is, you might want to split it up and make sure it's more readable, but in a simple scenario like ours, I think it's perfectly fine and readable to use the abbreviated ternary like we are.

What do you think about this PHP and Ruby comparison? Do you have other comparisons you find interesting between PHP and Ruby or comparisons with other languages?