Pages

Showing posts with label Article. Show all posts
Showing posts with label Article. Show all posts

Tuesday, February 2, 2016

Evil Traits or Poor Programming Skills

So I came across this nice little article about how evil Traits are, and I thought to my self, here is yet another developer who thinks we should all work in Assembly. Are traits evil? Of cause not. Can they be used in a wrong way? Sure they can. So can functions, classes, interfaces and so on. But you cannot blame traits for peoples bad choices. Now there is a lot of reference in this article to people with C++ background saying how wrong traits are, as these references should some how prove a point? I am positive that I have seen the same points being made against OOP by people with C background.

Let's take an example of trait usage. Let's say that we want to build an OOP database abstraction layer so that we can easily adopt code for other databases. Here is what we need for basic features.
  • Select Query class
  • Delete Query class
  • Insert Query class
  • Update Query class
Also we want some shared tools such as 'compile', so let's make an abstract class that the above mentioned can extend from, let's call this 'QueryBuilder'.

abstract class QueryBuilder {}

class SelectQuery extends QueryBuilder {}
class UpdateQuery extends QueryBuilder {}
class InsertQuery extends QueryBuilder {}
class DeleteQuery extends QueryBuilder {}

What does all 4 classes needs for starters, well the options of choosing one or more tables. No mater the query type, you will need to define at least one table. So this one is best put in 'QuryBuilder'. In the above mentioned article he wrote that one problem with traits was that you could change the access level of methods when adding them to a class. Let's get an example of why this is useful. Most databases, if not all, does not really need multiple tables for an insert operation. If we add table features to the 'QueryBuilder', then this would be possible. Let's go another way. Let's create a trait instead and see where this takes us. We will call this `QueryBuilder_Table` where we use underscore as naming convention since it's a cut of part of 'QueryBuilder'.

trait QueryBuilder_Table {
    protected function table(string $name, string $alias=null) {
        // ...
    }
}

Now that we have the table feature in a trait we can add it in different ways to each class. All 4 classes excepts a table name and an alias in their constructor. But since we have made the 'table' method protected in the trait, we can extend the features in some of the classes by simply changing the access level.

class SelectQuery extends QueryBuilder {
    use QueryBuilder_Table { table as public; }

    public function __construct(string $table, string $alias) {
        $this->table($table, $alias);
    }
}

class UpdateQuery extends QueryBuilder {
    use QueryBuilder_Table { table as public; }

    public function __construct(string $table, string $alias) {
        $this->table($table, $alias);
    }
}

class DeleteQuery extends QueryBuilder {
    use QueryBuilder_Table { table as public; }

    public function __construct(string $table, string $alias) {
        $this->table($table, $alias);
    }
}

class InsertQuery extends QueryBuilder {
    use QueryBuilder_Table;

    public function __construct(string $table, string $alias) {
        $this->table($table, $alias);
    }
}

Now your able to define multiple tables in classes such as 'Select', but not in 'Insert' while using the same trait. Could this be done with normal inheritance, sure it could, but we are not done yet. Also I might add that extending a class with normal inheritance also allows you to change the access level. So if this is something that makes traits evil, then maybe someone should read a little more about the options with class inheritance.

Fields is another great thing to add to a query, but we have two different scenarios. 'Select' for example defines fields/columns that should be returned while 'Insert' and 'Update' defines fields to insert/update with a value. So for this we make two traits 'QueryBuilder_Field_Selectable' and 'QueryBuilder_Field_Updatable'.

trait QueryBuilder_Field_Selectable {
    public function field(string $name, string $alias=null) {
        // ...
    }

    public function fields(string ...$name) {
        // ...
    }
}

trait QueryBuilder_Field_Updatable {
    public function field(string $name, $value) {
        // ...
    }
}

Of cause we exclude 'Delete' as it does not need either of these options. Let's move on to conditions, something needed for 'Select', 'Update' and 'Delete'. Again we create a trait 'QueryBuilder_Conditional'.

trait QueryBuilder_Conditional {
    public function condition(string $field, $value, string $operator="=") {
        // ...
    }
}

We could go on from here and add more, like join features etc. But let's move along to something else. We have 3 classes that share one thing, 'Delete', 'Update' and 'Insert' does not need to return a result set. Instead they would be better of returning a number of affected rows. This is a feature that is actually worth checking for, so it would not be well placed in a trait. Instead we create another abstract class named `QueryExecuter` that extends from `QueryBuilder` with a method called `execute()`. At the same time we add a similar `enquire()` method to 'Select' that returns a result set. This leaves us with 5 actual data types 'QueryBuilder', 'QueryExecuter', 'Delete', 'Insert', 'Update' and 'Select'.

abstract class QueryExecuter extends QueryBuilder {
    public function execute(): int {
        // ...
    }
}

The great thing about using traits in this way, is that we get a proper separation of the different functionality. Sure 'Update' and 'Select' could have a shared class with conditional options like a `QueryConditional` for example. But that would actually be wrong and provide a very poor design. You would be better of implementing the features separately in each class. Even though they share some similar methods, the functionality they use those methods to provide is completely different. One updates a set of rows/columns while the other fetches and returns a set of rows. So when would it ever make sense to check for 'QueryConditional'. Using traits they can share these tools without having any relation with one another. Sharing 'QueryExecuter' does make sense, because it provides the exact same functionality. It executes the query and return the number of rows affected by it.

In the above mentioned article, one of the claims for traits being so evil was that classes does not inherit the data type of a trait. Well thats sort of the point, and when used correctly it's actually a good thing. You are not meant to check for options provided by traits. You are meant to check for options provided by a specific class. How that class obtains those options is beside the point.

Let's take a last look at the first example. We could have added the 'table()' feature to 'QueryBuilder' as with a protected access level and then overwrite 'table' as public and call `parent`. But there are two things that traits does better in this scenario. Firstly you don't need to overwrite it and make an additional call to 'parent' in order to change the access level. Secondly what if you want to use 'QueryBuilder' for something else that should not have 'table' options. Maybe create a 'Condition' class that can be used to add multi-level conditions.

In this case you could extend your 'QueryBuilder_Conditional' to except 'QueryBuilder' instances, and you could use your 'QueryBuilder_Conditional' trait within your 'Condition' class to gain the conditional features. Remember that 'QueryBuilder' is used to provide the 'compile()' feature, which is not exclusive to 'QueryExecuter' or the other classes that we have made so far.

trait QueryBuilder_Conditional {
    public function condQuery(QueryBuilder query) {
        // ...
    }

    ...
}

class ConditionQuery extends QueryBuilder {
    use QueryBuilder_Conditional
}

In conclusion Traits are in no way evil. They are a brilliant addition to PHP and will save people a lot of time. Sure they can be used wrong, but as mentioned above so can everything else.

Monday, June 15, 2015

Facebook remains in the dark ages

What is HTML5? Most people would be able to answer this question, whether they are highly educated IT professionals or a hobby programmer, but at Facebook it seams as if they are still struggling with this strange concept.

The thing that I love the most about HTML5, is the fact that we no longer need any plug-ins to be installed in browsers. It's canvas and socket features replaces the old and terrible Java Applets. Don't get me wrong, I love Java. It's a nice programming language and it's great when you want to easily port programs across multiple architectures. But the Java Applets is one of the worst thing ever created, next to Microsoft's ActiveX (Along with their Browser). It will not be missed. The HTML5 Video and EME features replaces both Flash and Silverlight. Both of which brings nothing but instability and security vulnerabilities.

For a long time now, I have not had any plug-ins installed in my browser and I have not had any reason to. It seams that the vast majority of websites has either switched to full HTML5 or at least provide this as a second option. The few sites that don't, are not very important. At least that has been my observation until today.

My brother wanted to show me a video on my laptop. He navigated to Facebook and logged into he's account. He then searched for a specific video and tried to play it, but it wouldn't start because Flash is not installed in my browser. I don't use Facebook myself, so I have never noticed this. But Facebook, one of the worlds largest websites, do not have any support for HTML5 playback. Personally I have never liked Facebook, I cannot say why as I don't really know it myself. Nevertheless I have always pictured them as technologically advanced. Properly because I could not imagine a website being able to reach this magnitude of popularity while falling behind in this area. They proved me wrong.

Why am I writing about this? I have no idea. Maybe it's just the chock getting to me. Next to Google/Youtube, this was the last place that I would ever expect to be so far behind in technology. I mean this is freaking Facebook that we are talking about, and their only video solution is Flash? A technology that should have been extinct by now. And this is just the observation I made in the 2 minutes that my brother was trying to get this video to play. This is something that I would have expected from a small personal site where the owner had not yet had the time or resources to make the switch. But even those sites are up-to-date. The only one missing is the one that should have plenty of resources and highly skilled personal to do it, although I am starting to doubt the later.

Wednesday, May 27, 2015

The world of Root and Xposed Bridge

People have a tendency to install and enable things that they do not fully understand. In this article I will try to explain just what Root and Xposed Bridge is and how dangerous it can be. Don't get me wrong, I love both of these things, but it is important to be careful and not grant just any application these types of rights.

Let's picture a small village. In the middle of this village is a large bank. It is surrounded with a lot of smaller buildings. The bank represents the core Android system while the buildings are all of the Applications. All the people within each building can communicate with one another since they are all within the same building. If a building needs to communicate with another building, it has to send someone across town to the other building. It is then up to the people in that building to decide whether or not they want to let that person inside. While inside, the person can make a request or a delivery. Maybe he wants to borrow some sugar. He then delivers the response (in this case the sugar) back to his building. The same applies for the bank which is surrounded by guards. To make a request for a specific item in the bank, a building will need a permission slip for that item in order to bypass the guard watching it.

One building however has an Xposed Module implemented. In this case it is a specific type of person, I spy if you will. The building can send this person over to the bank and make him act as a guard. The bank and it's other guards will not not sense that anything is wrong. This spy can now move around in any section of the bank without any permission slip. He can steel items, place new items or make changes to the existing once without anyone asking questions. He can also disguise himself as a member of other buildings and walk around those without an invite. This spy is essentially a god amongst men.

In Android it allows applications to provide features not normally available, like changing theme and colors in any part of the system, create security modules that can restrict other applications from gathering specific information and much more. But it also allows application to do things that you might not want it to, like gathering information and uploading it to a server. Since the module can do whatever it wants, there is no way to restrict it.

Root is similar. It is the main built-in Administrator in the Linux kernel (Which Android is built on top of). In this case it acts as the emperor of the village. It is the main authority in the system and no one would dare to tell it no. It can move, do and behave just as it feels like without no one trying to stop it. The most important thing to note here is that Xposed Modules is able to acts as root, even if the device is not rooted. It is also important to note that gaining root via Xposed Bridge will not trigger your normal Root Popup window on rooted devices. So you will not even know that this has happened.

There is no doubt that devices with Xposed Bridge and Root enabled are much more fun. This article is not meant to scare anyone from rooting their devices or install Xposed Bridge on them. It is meant to inform people about the danger of doing so to make them more aware next time they enable an Xposed module or grant root to an application asking for it. Make sure that the application in question can be trusted, which most importantly mean that you should not allow this for Closed Source applications. If the source codes are close, there is no telling what has been implemented into the application.

So the next time you think about enabling an application in Xposed Bridge or grant root to an application, do some research first. Make sure that you can find a link to the source codes, make sure that the developer is contactable, do some searches to make sure that others have not warned about this application.

In any case, do not just blindly enable whatever the application asks for.

Friday, March 20, 2015

JNI / Android NDK

If you visit the Android developer page and read about Android's NDK, it will seam as if Google is trying to scare people from using it and just stick with Java. In most cases this will properly be the best idea. Java is a great language and does a good job for most tasks. However JNI is not as dangerous as Google is trying to make it. Most of Android is build on JNI and IPC. Information is being parsed in and out of JVM and between processes constantly, so why should applications not take advantage of this as well?

One thing to remember about JNI is that it creates a bit of overload to parse in and out of JVM. But depending on the task, this is not necessarily enough downside to keep away from it. The best way to figure out whether or not to use C/C++ or Java, is to test your task in both and then compare the result.

One good example of a task better suited for JNI could be some extensive file operations. For this example we will collect the content of the stat file for all currently running processes on a device. On my device running Android 5, we are talking about rounded 300 files. We add this to a loop which will run 100 times which in turn will create 3000 file read operations.

The first thing we need, is a basic activity to run our examples in.

MainActivity.java:
public class MainActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  StringBuilder builder = new StringBuilder();
  
  for (int i=0; i < 2; i++) {
   double start = System.nanoTime();
   int files = 0;
   
   for (int x=0; x < 100; x++) {
    String[] list = null;
    
    switch (i) {
     case 0: list = JavaCollector.collect(); break;
     case 1: list = NativeCollector.collect();
    }
    
    files += list.length;
   }
   
   double end = System.nanoTime();
   
   builder.append(i == 0 ? "JavaCollector" : "NativeCollector\n");
   builder.append("Files = " + files + "\n");
   builder.append("Time = " + ((end - start) * Math.pow(10, -9)) + " seconds\n");
   builder.append("\n");
  }
  
  TextView view = (TextView) findViewById(R.id.textview);
  view.setText(builder.toString());
 }
}

We also need a Java method to do the collection work. We will separate the native method and the Java method into two files in this example. It makes it easier to keep an overview.

JavaCollector.java:
public class JavaCollector {
 
 /*
  * Re-defined regexp to match directories in /proc with process id's
  */
 protected static final Pattern REFEXP_PID = Pattern.compile("^[0-9]+$");
 
 /*
  * The method that collects all the file data
  */
 public static String[] collect() {
  /*
   * Get a listing from the /proc directory
   */
  String[] procListing = new File("/proc").list();
  
  /*
   * Define our input stream
   */
  BufferedReader in = null;
  
  /*
   * Create a temp container for the file output
   */
  ArrayList<String> lines = new ArrayList<String>();
  
  /*
   * Handle each entity in /proc
   */
  for (String procEntity : procListing) {
   /*
    * We only want the pid directories
    */
   if (REFEXP_PID.matcher(procEntity).matches()) {
    try {
     /*
      * Open the sub directory stat file
      */
     in = new BufferedReader(new FileReader("/proc/" + procEntity + "/stat"));
     
     /*
      * Get the content of the stat file
      */
     lines.add(in.readLine());
     
    } catch (IOException e) {} finally {
     if (in != null) {
      try {
       /*
        * Close the file
        */
       in.close();
       in = null;
       
      } catch (IOException e) {}
     }
    }
   }
  }
  
  /*
   * Create and return a string array
   */
  return lines.toArray( new String[ lines.size() ] );
 }
}

And we cannot compare the above Java class to JNI without a native example as well.

NativeCollector.java:
public class NativeCollector {
 
 /*
  * Load our collector library
  */
 static {
  System.loadLibrary("collector");
 }
 
 /*
  * This is really a call to Java_com_example_NativeCollector_collect() in collector.cpp
  */
 public static native String[] collect();
}


collector.cpp:
JNIEXPORT jobjectArray JNICALL Java_com_example_NativeCollector_collect(JNIEnv *env, jobject thisObj) {
 /*
  * Open /proc
  */
 DIR* procDirectory = opendir("/proc");

 if (procDirectory != NULL) {
  /*
   * Create a temp container with minimum 100 indexes pre-allocated
   */
  std::vector<std::string> lines(100);

  /*
   * Create an input stream
   */
  std::ifstream in;

  /*
   * Create a variable for the proc entities
   */
  struct dirent* procEntity;

  /*
   * Handle each entity in /proc
   */
  while ((procEntity = readdir(procDirectory)) != NULL) {
   /*
    * We only want the pid directories
    */
   if (std::regex_match (procEntity->d_name, std::regex("^[0-9]+$") )) {
    /*
     * Open the sub directory stat file
     */
    std::string path = std::string("/proc/") + procEntity->d_name + "/stat";
    in.open( path.c_str() );

    if (in && in.good()) {
     /*
      * Get the content of the stat file
      */
     std::string line;
     std::getline(in, line);

     lines.push_back(line);
    }

    /*
     * Close the file
     */
    if (in) {
     in.close();
    }
   }
  }

  /*
   * Create Java return data
   */
  if (lines.size() > 0) {
   /*
    * Create a Java array
    */
   jobjectArray ret = env->NewObjectArray(lines.size(), env->FindClass("java/lang/String"), NULL);

   for (int i=0; i < lines.size(); i++) {
    /*
     * Place the line in a Java String
     */
    jstring stringObject = env->NewStringUTF( lines[i].c_str() );

    /*
     * Add the Java String to the Java Array
     */
    env->SetObjectArrayElement(ret, i, stringObject);

    /*
     * Release the Java String reference.
     *
     * Note: This is important. We can only have a limited ammount of Java objects
     * at a time and they are not auto released until we return to the JVM. And since we
     * are looping an unknown, but large, number of files, we could end up with a memory overflow.
     */
    env->DeleteLocalRef(stringObject);
   }

   /*
    * Return the array to JVM
    */
   return ret;
  }
 }

 /*
  * Return an empty array
  */
 return env->NewObjectArray(0, env->FindClass("java/lang/String"), NULL);;
}

If we compile and run this application, we will get the following result:
  • JavaCollector$collect: 21.2 seconds
  • NativeCollector$collect: 2.7 seconds

    This is not just slightly faster than Java, this is 87% faster. 
This is only a simple example. If it should be used in a real application, then depending on the amount of files and amount of data, it might be a good idea to make some sort of iteration mechanism to avoid memory overflow. But as the result shows, it is sometimes a good idea to check whether or not a JNI solution might be better. Java is not always the correct solution. 

So get started with:

Friday, October 31, 2014

How does Hacklang work

I must admit that I am not a fan of Facebook. Unlike 90% of the world, I do not, and have no intention of, ever owning an account. The list of reasons are long, and some of the things on that list have more to do with the people using it, rather than the service itself. Something just happens to normal people when entering the website, it's like watching one of the many talk-shows and reality programs on TV.

But although this article is about Facebook, it is not about the service that they are most famous for. This article is about a small extension to the PHP programming language, created by Facebook, called Hack, and the related Virtual Machine called HHVM. If you are a PHP programmer and either do not know about this or if you have not yet tried it, then I'll suggest you have a look at it. This extension provides features that PHP should have had ages ago. This article will not get into what Hack and HHVM is, I'll suggest that you visit the website http://hhvm.com if you are not already familiar with it.

What this article will focus on, is how HHVM/Hack acts. PHP is normally a dynamic typed language, but Hack introduces static typed features, and at the same time keeps compatibility with regular PHP. It's like mixing oil and water, and actually making them mix. The way it works, is that the VM mostly upholds the rules of PHP while the type checker upholds the rules of Hack. In other words, you can without any issues execute code that is not acceptable by the rules of static typing, but you will get errors when parsing it through the optional type checker. The errors from the type checker can also be removed by changing how strict it should be, which can be set pr. file. This allows you to mix dynamic typing and static typing, and still be able to use the type checker on the strict files.

class MyClass {
    public function test1(): void {
        $this->internal( Map{"key"=>1} );
    }

    public function test2(): void {
        $this->internal( Vector{true} );
    }

    private function internal(Map<string, bool> $param): void {
        // Code ...
    }
}

If we execute test1() from a browser, HHVM would not generate any errors. It would simply allow it. If we execute test2(), HHVM would break the request with an error. The reason for this is that HHVM follows PHP rules, which does not provide any generics. PHP however does allow one to define parameter type, which is the only thing that is being monitored for. The type checker on the other hand, would print a lot of errors here, first complaining about the wrong generics types in test1() and then complain about the wrong data type in test2().

class MyClass {
    public function test(): bool {
        return 1;
    }
}

The same applies for the return type. The above example will not conflict with HHVM. The only way to catch this problem, is by the type checker.

So the way that Hack is able to work along side PHP, is that the VM does not enforce any Hack rules. If you want to check your code for type safety, you will have to check it using the type checker. For the most part this will suffice. But the type checker is still a work in progress, and it does contain a few bugs.

class MyClass {
    public function test1(): void {
        $this->internal(Map{"key"=>new Map(array(
            "key"=>1
        ))});
    }

    public function test2(): void {
        $this->internal(Map{"key"=>Map{
            "key"=>1
        }});
    }

    private function internal(Map<string, Map<string, string>> $param): void {
        // Code ...
    }
}

Both test1() and test2() will parse the exact same value to internal(). However the type checker will only report an error on test2(). The wrong generics type in test1() will not be caught.

Thursday, October 30, 2014

PHP Traits extends OOP posibilities

OOP if a wonderful concept in programming. People have different opinions about it, but I for one love it. First of all you have all of your work divided into groups (Classes), and adding other concepts like namespaces or packages, your classes becomes sub-groups in even larger groups. It makes it easy to keep track of your work in large code bases, and it reduces the chance of things colliding, especially in environments where 3'rd party code can be added dynamically (E.g. CMS modules for an example). It also allows classes to share code with one another. If you want to create a class that adds functionally to an existing class, you can extend from that class, and adopt the already existing code into your new class. Then all you have to do, is change and/or add whatever you had in mind, without having to copy/paste the content of one class into another. At the same time, adding to and/or fixing something the first class, will automatically be appended to the second one.

But OOP does have it's limitations. For one, you can only extend from one class. So if you want to adopt code from two classes, you are out of luck. You can of course implement as many interfaces as you'd like, but interfaces only defines the structure of a class, and does not provide any pre-done work. This has now changed in PHP with the introduction of Traits since version 5.4. A Trait is something like an abstract class, the difference being that you do not extend from it, instead you sort of includes it's content within your class. It can somewhat be compared to extending objects in JavaScript via the prototype property, and you can include as many Traits as you'd like.

trait Snipped1 {
    public static function printMessage() {
        echo "Prints a text!";
    }
}

trait Snipped2 {}

class Example {
    use Snipped1, Snipped2;
}

Example::printMessage();

The class above will contain all the content from both Traits. Also unlike when extending two classes, all static content in Traits, like static properties, will have their own instance pr. class that uses them. So changing the value of an static Trait property from one class, will not change the value in other class, using the same Trait.

One thing that Traits does not do, is parse their type to classes using them. Content that you include from a Trait, will be treated as if it belongs to the class itself. This means that you can't use something like instanceof to check whether or not a class uses a Trait. There are ways to check, but these ways are slow and not very handy. And there is nothing wrong with this, it is meant to work this way, because classes does not implement or inherit from Traits, they simply copy/paste their content.

Personally I did not find Traits very useful at the beginning, mostly because if they are used wrong, they can create a lot of chaos in your code. Much more than chaotic inheritance. But after playing around with them, I found that they can be handy if you include interfaces. By using an interface to define a class structure and then add a Trait with some partial code, you will have what can be considered an abstract class divided into two parts. One containing the partial code and one containing the details about how a class should look.

interface ISnipped {
    public function printMessage();
    public function secondMethod();
}

trait Snipped {
    public function printMessage() {
        echo "Prints a text!";
    }
}

class Example implements ISnipped {
    use Snipped;

    public function secondMethod() {
        // Do something
    }
}

$example = new Example();

if ($example instanceof ISnipped) {
    $example->printMessage();
}

The above example can be compared to the example below
public abstract class Snipped {
    public function printMessage() {
        echo "Prints a text!";
    }

    public abstract function secondMethod();
}

class Example extends Snipped {
    public function secondMethod() {
        // Do something
    }
}

$example = new Example();

if ($example instanceof Snipped) {
    $example->printMessage();
}

Both examples provide much the same structure, but using Traits we can adopt from more than one. All we have to do, is implement more interfaces and add more traits.

Monday, October 27, 2014

Wordpress

A while ago, I was hired to extend a web site for a small company. The web site had been build by one of their graphics designers, who did not normally work with programming. As a result, this site had been built using Wordpress, because this was the easiest system for this non-programmer to start with, while he at the same time had to learn the basics of HTML, CSS and PHP. The custom work that he had done was not the best, but still quite impressive considering the time frame and the fact that he did not know anything about coding when he started. But this article is not about designers turning programmers. It is a small overview of Wordpress, and about some of the reasons why I would never build anything with in, unless I am forced to.

Starting on this site, I did not know anything about Wordpress. All that I knew was that it used to be a small blog system, which apparently had grown larger over time. I started reading some of the documentation, and it did seam like something worth looking into. I especially liked the idea of their action and filter callbacks. However, once I got started, I became less impressed.

First of all Wordpress is missing a lot of rules. Sure they have their Plugin.php file, but there is no rules as to what this file should contain. If you compare it to Drupal, which have a module file containing hooks with strict naming schemes, Wordpress introduces the same policy as PHP, where no standard for anything exist. Now I do like PHP, but it would be a lot better, if they implemented parts of Hack into it. Static Typing for one.

Their plugin system is also very minimal. If you need to add some additional tings to the existing blog system, then this is fine. But if you need to add some extensive work into Wordpress, you will need to integrate this directly into the "Theme" files. Also while talking about the Theme files, I think that the people behind Wordpress has misunderstood the word "Theme". These files actually makes up most of the system. They work as bootstrap of some sort, they contain a lot of the site logic as well as the Themes. All in all, they act much like MVC wrapped into one single "Theme" file.

The worst part of Wordpress, some of which was mentioned above, is their action and filers system. The idea is great, but it is extremely pure designed. This is the part that would have benefited the most by some stricter rules. One of the things that one should avoid when working with PHP, is their dynamic caller functions "call_user_func" and "call_user_func_array". Requests that normally takes nanoseconds to load, will take milliseconds and sometimes seconds, when introduced to the above functions. And this is only by a few calls pr. request. Wordpress has integrated this into the entire core of the system. Even before the initialization is done, these functions has been called numerous times. After that, even more calls is done by more of Wordpress's functions, by themes and by plugins. Depending on what you have installed and enabled, you can end up in 3 digit calls to these extremely slow functions. This is the worst design that I have ever seen in any framework for any language, and I cannot stop thinking about those poor CPU's that has to process all of this unnecessary code.

A better design would have been to implement either a strict procedural design, allowing only functions to be parsed, which can be executed without any additional resources. Or implement a strict OOP design by using interfaces, much like how callbacks works in Android.

If you just need a small blog site with few visitors and if you hate your server, then by all means, use Wordpress. But if you want a serious site with many visitors, if you love your server and if you'd like to have some nice coding standards, I would suggest using another CMS or build one using one of the many frameworks available. Wordpress is a mess, there is no standards of any kind, most of your work will have to be implemented using different hacks to work properly and it will rape your server daily.

Thursday, October 9, 2014

Microsoft Windows? Why?

I have not been a Windows user since XP was the new big thing, and even before that time, I was not a big fan of Windows. Why? Well Windows have always had a thing where it was trying to push every single one of my buttons, which often resulted in hardware pieces (Mouse, Keyboard, Monitors, etc.) being thrown across a room. This ended up becoming to expensive, and I decided to give Linux a try instead, which have saved me a lot on hardware purchases.

But living in a Microsoft world while being the guy known to have IT knowledge, it is not so easy to get rid of Windows 100%, although you might not use it at home. Once in awhile, people you know will come to you with their Windows problems. Most of the time I tell them to use a system that I want to support, if they require me to do so. I did not switch away from my Windows problems just to take on every one else's.

But for some reason I did not say no when I friend of mine came to me to get help formatting he's laptop. I thought that since Windows is now at version 8, a lot must have changed since the old XP. A quick format and a few driver installs would properly not take up to much of my time, especially since all the drivers was stored on a USB pen drive. But just as I remember it, things are never that easy with Windows. The installation went fine, the newly installed Windows booted without issues, only a few driver installs remained. I plugged-in the USB pen drive and opened 'My Computer', just like I would do on my Linux machines, which takes about half a second to load USB devices. But Windows did not load it, instead it pops up with a small yellow driver install notification in the button right corner? Well okay. But then it fails to locate a driver? A simple UNIVERSAL Mass Storage device with a Microsoft msdos partition table containing a Microsoft Fat32 file system, fails to load on a brand new Microsoft Windows 8 operating system?

I plugged-in the USB pen drive into my own laptop, running on Fedora 20, and my file manager opened right away, displaying the content of the drive. Now which of these operating system is known for being so user friendly?

I cannot specify how I managed to get this drive working. I spent about an hour playing around in the control panel, unloading/loading drivers, plug/unplugging the USB pen drive, trouble shooting and much more. Finally at some point, for some reason, it started working. But I would really not call this user friendly, especially since this is just one small example of the many issues one will stumble upon, when working with Windows. This operating system takes to much of once time on ridicules tasks like this and it increases your blood pressure to a very dangerous level. Why people keep insisting on using it, I really don't know. I find *nix systems like Linux, OSX and such, much more friendly to work with. Use those and you might even live longer.