Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows the first argument of "extend" and "defaults" to be passed by reference #3

Closed
wants to merge 4 commits into from

Conversation

tgriesser
Copy link

Provides the option of passing the first argument by reference, directly modifying the object.

Current syntax:
$object = array('k1' => 'a2'); $object = __::extend($object, array('k1' => 'v1', 'k2' => 'v2')); // $object === array('k1'=>'v1', 'k2' => 'v2');

With changes:
$object = array('k1' => 'a2'); __::extend(&$object, array('k1' => 'v1', 'k2' => 'v2'));
OR
$object = __::extend($object, array('k1' => 'v1', 'k2' => 'v2')); // $object === array('k1'=>'v1', 'k2' => 'v2');

@brianhaveri
Copy link
Owner

Hi Tim,

This does appear to be the way Underscore.js works, so following that approach seems correct. Before merging this in, I want to consider a few things. Feel free to comment on any of these issues/questions.

OO-style calls
How would this work in an OO-style call? Here are the PHPUnit tests I would expect to pass for extend:

// Passes
$object = array('k1'=>'a2');
__::extend(&$object, array('k1'=>'v1', 'k2'=>'v2'));
$this->assertEquals(array('k1'=>'v1', 'k2'=>'v2'), $object);

// Fails
$object = array('k1'=>'a2');
__(&$object)->extend(array('k1'=>'v1', 'k2'=>'v2'));
$this->assertEquals(array('k1'=>'v1', 'k2'=>'v2'), $object);

Warnings
Perhaps I'm missing something obvious, but I'm confused why referencing within a function call doesn't throw an error under E_DEPRECATED on my machine running PHP5.3.6. From the PHP docs, I would expect a warning:

http://php.net/manual/en/language.references.pass.php :
Note: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to
correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.

Other methods
What other methods would this apply to outside of extend and defaults?

Cheers,

Brian

@tgriesser
Copy link
Author

Not really sure that this can be done... setting a reference in the function definition pretty much breaks the ability to pass anything which is not a variable as the first argument... which would defeat the purpose of the project. So it's probably not worth it...let me know if you have any thoughts or ideas.

I'm also not really sure why there wasn't a warning thrown, possibly because of all of the custom function handling. Regardless it's probably not a good idea to set it up that way since the feature is deprecated whether a warning is thrown or not.

@tgriesser tgriesser closed this Oct 9, 2011
@jrschumacher
Copy link

They only way I've been able to "dynamically" pass by reference is either create two methods or via an array:

<?php

class __ {
  var $_wrapped = null;
  // var $_wrappedRef = null; Optional if using $_wrapped in way which breaks references
}

function __($item=null) {
  $__ = new __;
  $_item = $item;

  // Handle references
  if(is_array($item)) {
    $_item =& $item[0];
    $__->_wrapped =& $_item;
  }
  // Non-reference
  else {
    if(func_num_args() > 0) $__->_wrapped = $_item;
  }

  return $__;
}

// Telling underscore to use as reference
$v = 1;
$a = array(&$v);
$u = __($a);
var_dump($v);
$v++;
var_dump($u);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants