Beware of the underscore

Posted by Jad on September 25, 2008

Have you ever tried using underscores (_) in your controllers variables that you are passing to the view using a combination of Controller::set() and compact()? Well, if you did, you must have realized that they never make it there, right? I haven’t submitted it as a bug yet but here it is:

class SandboxController extends AppController {
    var $uses = null;
    var $layout = 'sandbox';
    function beforeRender(){}
    function index()
    {
        $foo = 'foo';
        $bar = 'bar';
        $foo_bar = 'foobar';
        $this->set(compact('foo', 'bar', 'foo_bar'));
        $john = 'john';
        $doe = 'doe';
        $john_doe = 'john_doe';
        $this->set(compact('john', 'doe'));
        $this->set('john_doe', $john_doe);
    }
}

Now, in your view:

echo $foo . "<br />";
echo $bar ."<br />";
echo $foo_bar ."<br />";
echo "<br /><br />";
echo $john ."<br />";
echo $doe ."<br />";
echo $john_doe ."<br />";

Finally, the returned output:

underscore-bug

Anyone knows if that’s how it’s supposed to act?

Update: there is a way to actually get those variables intact. Thanks to Taylor for pointing it out.

$this->set(compact($foo, $bar, $foo_bar), false);
Trackbacks

Trackbacks are closed.

Comments

Leave a response

  1. klevo Thu, 25 Sep 2008 21:11:42 EDT

    If you feed the set function with an array, the underscored words get camelCased. So your $foo_bar will be $fooBar. Camel cased variables are Cake’s coding standart and this is probably done with the intention when putting a data array from the Model::find() operation to set().

  2. dave Thu, 25 Sep 2008 23:10:30 EDT

    i encountered this problem at one time. i think i remember that the variables get sent to the view as fooBar. i just make a point of not using an underscore anymore.

  3. Jad Thu, 25 Sep 2008 23:22:42 EDT

    @all: thanks for dropping by

    @klevo: if that’s the case, then it should check if a model with that name exists first, no? would make more sense if you ask me.

    @dave: i have a hard time changing my coding conventions to work around something that is not functioning correctly ;)

  4. hydra12 Fri, 26 Sep 2008 00:19:22 EDT

    I think they intend for things to work that way (I’m not sure why). For instance, if you create a controller called myController, and name your view myController.ctp, you’ll get a file not found error. You have to name the view my_controller.ctp. It seems to be a convention in cake.

  5. rafaelbandeira3 Fri, 26 Sep 2008 00:23:38 EDT

    @klevo: actually CamelCase and camelBack, Inflector::variable() transform your underscored_string in a camelBackedString.

    @Jad: I think it would make more sense to make all vars have their names pimped by Inflector::variable();

  6. taylor luk Fri, 26 Sep 2008 04:03:27 EDT

    Here is the work around.. Either set one variable at the time or when doing pass set pass false as second variable.

    $this->set(’underscoredwords’, ‘ok’);

    $this->set(array( ‘underscoredwords’ => ‘ok’, ‘cakestoprewritemyvars’ => ‘true ), false)

    $this->set(compact(’underscoredwords’), false);

    hope this help

  7. Jad Fri, 26 Sep 2008 04:10:04 EDT

    @taylor: nice!! haven’t checked the code but that definitely fixes it.

  8. Nik Chankov Mon, 06 Oct 2008 16:20:53 EDT

    I also noticed this “bug” and I know that I should not use compact with underscored vars.

    Although it’s more convenient, I’ve always used $this->set(’varname’=>’varvalue’); For me it’s more clear.

    the approach proposed from taylor luk - ya, it could do the job, but it is so complicated :)

Comments