6
\$\begingroup\$

This is a polyglot function I've made out of fun.

The goal is to grab n arrays (or Javascript Objects) and 'extend' them in order to obtain a single array with all the values.

This function runs both in Javascript and PHP.

Please, try to ignore some kludges on my code.

Here is my 'art':

function array_extend() {

    //Detects if we are running in Javascript or PHP
    //In PHP, this will be false because PHP only parses
    //escape sequences in double-quoted strings (except the sequence \')
    $javascript = '\0' == "\0";

    //PHP arrays support 'key=>value' pairs, JS arrays don't.
    $result = $javascript ? new Object() : array();

    $arguments = $javascript? arguments : func_get_args();

    $get_keys = function($elem){
        if('\0' == "\0")//PHP complains if I use the var $javascript
        {
            $object = Object;
            return $object['keys']($elem); //PHP doesn't like the Object.keys syntax
        }
        else
        {
            return array_keys($elem);
        }
    };


    for($j = 0, $length_args = $javascript? $arguments['length']: count($arguments); $j < $length_args; $j++)
    {
        $keys = $get_keys( $arguments[$j] );

        for($i = 0, $length_keys = $javascript? $keys['length']: count($keys); $i < $length_keys; $i++)
        {
            $result[$keys[$i]] = $arguments[$j][$keys[$i]];
        }
    }

    return $result;
}

Example of usage:

array_extend([1,2,3,4,5],[9,8,7,6,5,4,3,2,1,0]);
//should return the last elements in the array:

array_extend({'a':1, 'b':2, 'c':3},{test:'nice'});
//Javascript: returns {'a':1, 'b':2, 'c':3, test:'nice'}

array_extend(array('a'=>1, 'b'=>2, 'c'=>3), array('test'=>'nice'));
//PHP: returns array('a'=>1, 'b'=>2, 'c'=>3, 'test'=>'nice')

What do you guys think?

What can I improve? Where should I have done something better?

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Wait....so you made a function that compiles to both PHP AND Javascript??? \$\endgroup\$
    – jsanc623
    Commented Feb 6, 2015 at 20:25
  • \$\begingroup\$ @jsanc623 Yes, that's exactly it. You can fire up your console, paste it and use it OR you can slap it in a PHP file and run this bad boy! \$\endgroup\$ Commented Feb 6, 2015 at 20:33
  • 1
    \$\begingroup\$ Wh...why?? What are you trying to build? Please tell me this is just a learning exercise... \$\endgroup\$
    – jsanc623
    Commented Feb 6, 2015 at 20:50
  • \$\begingroup\$ @jsanc623 I was bored and simply made this. No, it isn't an exercise. I really just made this out of fun. I saw a question on stackoverflow to do something similar (it wasn't asking a polyglot) and did this. To be honest, I enjoy making this kind of stuff. \$\endgroup\$ Commented Feb 6, 2015 at 20:53
  • 1
    \$\begingroup\$ @jsanc623 I don't see much that I can improve. I could use better scoping (since this function is 'leaking' into the window object). But the var keyword isn't allowed outside classes, in PHP. If there was a way to make a single local variable with Javascript in a non-obstructive way that works for both languages, I would use it. But that's it. \$\endgroup\$ Commented Feb 9, 2015 at 17:43

1 Answer 1

2
\$\begingroup\$

You may want to replace object key access notation with dot notation.

For example, instead of the following.

$object['keys']($elem);

Write this.

Object.keys($elem);

This works, because Object is interpreted as a constant, dot as concatenation, and keys($elem) as function call. Use of undefined constant doesn't warn if the code with it is not executed. Unknown functions don't error if they aren't called.

\$\endgroup\$
1
  • \$\begingroup\$ For some reason it failed to me. A LOT! That's why I used that weird kludge. But it worked now and it's worth noticing. Also, you can add there that I forgot the order of the variables. $i should be in the first loop and $j should be in the 2nd. If you find a way to make a local variable for Javascript without the keyword var (sounds insane, I know), I would thank you a lot! \$\endgroup\$ Commented Feb 10, 2015 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.