Loading...

Some pitfalls while switching from PHP to D

posted on Fri, June 06th, 2008

Generally writing D code is straight forward, but at certain points I found myself banging my head on the table. Some things are just not working as I am used to it from PHP. That begins with typing. Everything needs to be typed and conversion between types need to be made explicitly. I'm just not used to it. Getting a char[] converted into an integer seems such an easy tasks, but when it comes to the point where you actually need it, it becomes very unusual for a PHP developer. In this short article I will report about some of the pitfalls I had to solve for my first little D project. I do not claim that it is beautiful code or even if it is free from errors and possible misconceptions, but it worked for me so far.

Imports

Before starting about conversions and other problems I would like to add a note on imports of packages as this was one of the things that I was struggling in combination with the type conversion. There are several import possibilities. The most basic one is to import the package by just using the import statement. This just imports the package as is with private visibility to the module. It is possible to define the visibility by adding a prefix to the import statement. These prefix can be the same as for functions and methods. Additionally it is possible to create a new namespace for the imported symbols. That way you can access the imported functions with your own given identifier, which can be helpful for clarity and for separation of interfaces that use multiple overridden classes. Another possibility to avoid name collisions is to use static imports. In case a static import is made the package needs to be accessed by its fully qualified name, eg. tango.text.convert.Integer.format(). Below you see some import examples with comments:



Type conversions

Tango provides some helpful functions, for handling type conversions. They can be found in the Tango.text package and allow easy conversions between types, while still providing enough parameter to convert types very specifically if needed. I took me some time to figure out how to use the package as documentation and examples are scarce. So here are some examples how to easily convert integer in strings and back. I used to import the package with renamed import to have a clear separate namespace.



Function returns

This is another issue which I became quite used to with PHP. In PHP it is easy to return an object, array, integer, string or whatever you want with a function, but at the same time you can return also a bool. It is not specified what you return from a function, because nothing is typed. So it became common practice to me to return false instead of the actual value, if something went wrong in the function. This way I used to handle the errors, because I could handle the error where the function was called, instead of handling it in the function itself.
This is not working that way in the D, because everything is typed ;). So you need to specify what type is returned by the function. In consequence it means I need to reconsider my error handling strategy. Everything needs to be handled within the function itself.



Dynamic Arrays

Although there are dynamic arrays in D, they don't behave like dynamic array's in PHP. I was used to fill PHP arrays with the following code:



But in D dynamical arrays are not as dynamic as in PHP. You can create dynamic arrays, but the only difference to static arrays is that you can read and write the length of the array. It is not possible to easily add a new element to array. You need to change the size of the array first to add a new element. This is a bit clumsy, but there are solutions. Tango provides a package called collections tango.util.collection, where several different collection implementations, which are similar to some from Java. There are basically four different implementations: Bags, Set, Sequences and Maps. To solve my problem I used sequences. You can see the example below:



I couldn't find a method in the sequence implementation that returns the length of the sequence. This is why I needed to convert the sequence in an array in order to get the length, which I needed for another for loop.



Object Orientation

One last bit at the end. What I found a bit strange was that it was possible to reference to methods within a class without the this statement. It didn't made a difference calling a function with this or not.


 
 

Comments

1
.(JavaScript must be enabled to view this email address) on
Jul 30, 2008

You can concatenate to dynamic arrays with ~
I think its cleaner then PHP

import tango.io.Stdout;

void main()
{
char[][] array;

array ~= "Hello";
array ~= "World!";

foreach(str; array)
Stdout(str)(" ");
}

Also accessing any member of a class doesn't need to have this, the compiler will assume this. Same rease you dont have to do this.limit

2
Lars on
Jul 30, 2008

Hi Wyverex, thank you very much.

That's indeed very clean and straightforward. I've just had no idea that a two dimensional char array would just do that.

Regarding the 'this' statement. How does the compiler than differentiate between a class variable and a method variable.

For instance:

class foo {

uint id;

private bool get_id()
{
uint id;

// without 'this' would also
// return the class id?
return id;

// so how does the compiler handle
// this?
return this.id
}
}

/lars

3
Lars on
Jul 31, 2008

Found the solution to the scope problem in the "Learn to Tango with D" book.

module parser;

int state;

class Parser
{
int state;
int outerState() {return .state;}
int innerState() {return state;}
}

The function outerState returns the value of the state variable outside the class, whereas innerState returns the value of the class variable. The important difference is that all variables without the class scope need a "." (dot) in front of the variable.
This notation is a bit strange to me, but at least I know how to differentiate between the scope.

/lars

 
 

Leave a Comment

Commenting is not available in this weblog entry.