ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Challenge 2 : moveable function arguments

July 10, 2008 6:18am

Subscribe [0]
  • #1 / Jul 10, 2008 6:18am

    xwero

    4145 posts

    I’ve searched to find a way to do;

    address($name = 'me');
    address($street = 'fifth avenue');

    Which isn’t possible. So the challenge is how do you hack user defined function arguments.

  • #2 / Jul 10, 2008 6:22am

    Daniel Eriksson

    31 posts

    You pass them as an array. 😊

  • #3 / Jul 10, 2008 6:26am

    xwero

    4145 posts

    too much typing.

    address(array('name'=>'me'))
  • #4 / Jul 10, 2008 7:29am

    richthegeek

    242 posts

    perhaps use an ordering integer at the start:

    address( 123, $name, $street, $city);
    address( 13, $name, $city );
    address( 2, $street );

    an example of a function that works using this might be:

    function address( $order = '123' )
    {
        $arg_names = array( 'name', 'street', 'city' );
        $args = func_get_args();
        foreach( str_split( $order ) as $i=>$num ) {
            $arg_name = $arg_names[ $num - 1 ];
            $arg = $args[ $i + 1 ];
            $$arg_name = $arg;
        }
        
        // continue as usual
    
    }
  • #5 / Jul 10, 2008 7:38am

    xwero

    4145 posts

    Then you need to add an extra argument.

    I forgot to mention that if all the arguments are present you should be able to do

    address('me','fifth avenue')

    like you normally add arguments to the function.

  • #6 / Jul 10, 2008 7:55am

    mironcho

    119 posts

    Another solution, similar to using array solution but with different approach:

    function address()
    {
        foreach (func_get_args() as $arg)
        {
            if (preg_match('/^([a-z0-9]+):(.+)$/', $arg, $matches))
            {
                $$matches[1] = $matches[2];
            }
        }
        
        // ...
    }
    
    address('varname1:test', 'varname2:blabla');
  • #7 / Jul 10, 2008 8:06am

    xwero

    4145 posts

    This is starting to look like my solution but you still have to add the names even if all the arguments are added.
    The downside of this solution, and mine, is that it’s function bound but that is because of the func_get_args function.

    Mironcho i like to add curly brackets around the variable part of the variable variable for faster detection.

  • #8 / Jul 10, 2008 9:36am

    mironcho

    119 posts

    Well, you can set default values for arguments if you know exact number of maximum expected arguments (and if this number isn’t too big 😉 ), and then check if all arguments are presented:

    function address($var1 = '', $var2 = '', $var3 = '')
    {
        if (func_num_args() < 3)
        {
            foreach (func_get_args() as $arg)
            {
                if (preg_match('/^([a-z0-9]+):(.+)$/', $arg, $matches))
                {
                    ${$matches[1]} = $matches[2];
                }
            }
        }
        
        // ...
    }
    
    address('var1:test', 'var3:blabla');
    address(1, 2, 3);

    There are some downsides though:
    - it wouldn’t be convenient, if you need to use too many arguments
    - if you use the shorter calls (e.g. - address(‘var1:test’); ), the other arguments will be always defined in the function’s scope with their default values

  • #9 / Jul 10, 2008 9:37am

    codemole

    2 posts

    My mind can only think of something similiar to mironchos approach, except for passing key/value pairs as separate arguments, like:

    function address('name', 'me', 'street', 'fifth avenue');

    If the first argument matches one of the argument names, treat it as key/value pairs, otherwise - just as individual arguments. It’d give a chance to pass not only strings to the function that way.

    Can’t think of anything else apart from writing a short array-creating function ( function a($key, $val); ) to ease the pain a little 😛

  • #10 / Jul 10, 2008 9:45am

    wiredesignz

    2882 posts

    OOPS,

    $person = new StdClass();
    
    $person->name = 'me';
    $person->street = 'fifth avenue';
    
    function address($person)
    {
        foreach (get_object_vars($person) as $key => $value) { ... }
    }

    I have no idea what you intend to do with the data, but anyway.

  • #11 / Jul 10, 2008 9:48am

    richthegeek

    242 posts

    to make codemole’s example work:

    function address()
    {
       $fields = array( 'name', 'street', 'city' );
       $args = func_get_args();
       
       if( in_array( $args[0], $fields ) )
       {
          for( $i = 0; $i < count( $args ); i++ )
          {
              $key = $args[$i++];
              $val = $args[$i];
              $$key = $val;
          }
       } else
       {
           foreach( $fields as $i=>$field )
           {
              $$field = $args[$i];
           }
       }
       
       // continue as before.
    
    }
  • #12 / Jul 10, 2008 10:41am

    xwero

    4145 posts

    @mironcho : i assumed the function argument all have a default otherwise it would be an (almost?) impossible challenge. But your solution is still function bound. i’ve found a way to create a function that makes it possible to add this to all functions that could use this functionality.

    @codemole : adding key value pairs as arguments doubles the argument count which is not wanted.

    @wiredesignz : creating an object like in your snippet looks even uglier to me than the array solution and then the function only can accept an object. It doesn’t matter what the function does but lets say it builds a microformat marked up output.

  • #13 / Jul 10, 2008 10:56am

    wiredesignz

    2882 posts

    @xwero, why comment on my solution?, I gave the guy an option to consider. He will choose whichever works for him.

  • #14 / Jul 10, 2008 11:03am

    xwero

    4145 posts

    Ah yes now i see 😊 I was beginning to think wiredesignz lost his love for little code 😊

  • #15 / Jul 10, 2008 11:07am

    wiredesignz

    2882 posts

    OOPS again, my bad… you are the OP, comment away. :lol:

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases