[Proto-Scripty] Re: weird issue with .each and objects

2010-10-10 Thread T.J. Crowder
Hi,

Your problem is in your Test class. You're creating an `options`
object on the prototype of your class, which means that it will be
*shared* by all instances of your class. Since your constructor is
writing to properties on that shared object, naturally multiple calls
to the constructor overwrite each others' values:

var t1 = new Test(0, {first: 'Fred', last: 'Flintstone'});
var t2 = new Test(1, {first: 'Barney', last: 'Rubble'});
alert(t1.options.first); // Alerts Barney, not Fred

A lot of times, you *do* want to put defaults for properties on the
prototype and the override them (if necessary) on the instance itself
(it's more memory-efficient to share default values; the instance will
get its own copy if you assign a value to it on the instance), but
you're not doing that -- you're writing to properties of the property
(`this.options.first`), not the property itself (`this.options`).

The fix in your case is simple: Remove the `options` property from
your `Class.create` call and instead put it in the constructor
function:

Test = Class.create({
        initialize:function(count,obj){
this.options = {};
                this.options.id = count;
                this.options.first = obj.first;
                this.options.last = obj.last;
        }
});

That was the minimalist change; you can make it a bit more brief:

Test = Class.create({
        initialize:function(count,obj){
this.options = {
                id:count,
                first: obj.first,
                last:  obj.last
};
        }
});

Barring other issues (I haven't read through the other code in detail,
this jumped right out at me), that should sort it out.

Off-topic: It looks odd that you don't have `var` in front of your
various class names, e.g. `var Test = Class.create` rather than `Test
= Class.create`. Have you already declared the vars somewhere else?
It's just, if you haven't, you're relying on the horror that is
JavaScript's implicit globals[1], which I would STRONGLY recommend
against doing.

[1] http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html

HTH,
--
T.J. Crowder
Independent Software Engineer
tj / crowder software / com
www / crowder software / com

On Oct 10, 4:25 am, Steven Albarracin stevenalbarra...@gmail.com
wrote:
 /*
 Basically I'm trying the pass an array of objects and pass them into
 the Test class, but it only seems to be passing in the last object in
 the array...
 */

 // class to store the id, first, last name
 Test = Class.create({
         options:{},
         initialize:function(count,obj){
                 this.options.id = count;
                 this.options.first = obj.first;
                 this.options.last = obj.last;
         }

 });

 // the array of the first and last name items
 people = [{first:Santa,last:Claus},
                   {first:John,last:Doe},
                   {first:Jane,last:Johnson}];

 // displaying the items to FF console,
 // open your console and click on the object and hit options to see
 the parameters
 Start ={
         init:function(people){
                 people.each(function(obj,count){
                         //this shows looping through the array correctly
                         Start.log(obj);
                         //in theory this should be showing the class with 
 each array item
 instead it s storing the last item
                         Start.log(new Test(count,obj));
                 });
         },
         log:function(message){
                 if(window.console  console.log) console.log(message);
         }

 };

 Start.init(people);

 /*
 console will show something like this

 Object { first=steven,  more...}
 Object { options=Object}   -- click these, notice they dont match
 the object above instead show last item
 Object { first=John, more...}
 Object { options=Object}  -- click these, notice they dont match
 the object above instead show last item
 Object { first=Jane, more...}
 Object { options=Object}  -- click these, notice they dont match
 the object above instead show last item

 Can someone tell me whats wrong here, thanks
 */

-- 
You received this message because you are subscribed to the Google Groups 
Prototype  script.aculo.us group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.



[Proto-Scripty] Re: weird issue with .each and objects

2010-10-10 Thread Steven Albarracin
Thanks for your suggestions and recommendations...

On Oct 10, 6:08 am, T.J. Crowder t...@crowdersoftware.com wrote:
 Hi,

 Your problem is in your Test class. You're creating an `options`
 object on the prototype of your class, which means that it will be
 *shared* by all instances of your class. Since your constructor is
 writing to properties on that shared object, naturally multiple calls
 to the constructor overwrite each others' values:

 var t1 = new Test(0, {first: 'Fred', last: 'Flintstone'});
 var t2 = new Test(1, {first: 'Barney', last: 'Rubble'});
 alert(t1.options.first); // Alerts Barney, not Fred

 A lot of times, you *do* want to put defaults for properties on the
 prototype and the override them (if necessary) on the instance itself
 (it's more memory-efficient to share default values; the instance will
 get its own copy if you assign a value to it on the instance), but
 you're not doing that -- you're writing to properties of the property
 (`this.options.first`), not the property itself (`this.options`).

 The fix in your case is simple: Remove the `options` property from
 your `Class.create` call and instead put it in the constructor
 function:

 Test = Class.create({
         initialize:function(count,obj){
                 this.options = {};
                 this.options.id = count;
                 this.options.first = obj.first;
                 this.options.last = obj.last;
         }

 });

 That was the minimalist change; you can make it a bit more brief:

 Test = Class.create({
         initialize:function(count,obj){
                 this.options = {
                     id:    count,
                     first: obj.first,
                     last:  obj.last
                 };
         }

 });

 Barring other issues (I haven't read through the other code in detail,
 this jumped right out at me), that should sort it out.

 Off-topic: It looks odd that you don't have `var` in front of your
 various class names, e.g. `var Test = Class.create` rather than `Test
 = Class.create`. Have you already declared the vars somewhere else?
 It's just, if you haven't, you're relying on the horror that is
 JavaScript's implicit globals[1], which I would STRONGLY recommend
 against doing.

 [1]http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html

 HTH,
 --
 T.J. Crowder
 Independent Software Engineer
 tj / crowder software / com
 www / crowder software / com

 On Oct 10, 4:25 am, Steven Albarracin stevenalbarra...@gmail.com
 wrote:

  /*
  Basically I'm trying the pass an array of objects and pass them into
  the Test class, but it only seems to be passing in the last object in
  the array...
  */

  // class to store the id, first, last name
  Test = Class.create({
          options:{},
          initialize:function(count,obj){
                  this.options.id = count;
                  this.options.first = obj.first;
                  this.options.last = obj.last;
          }

  });

  // the array of the first and last name items
  people = [{first:Santa,last:Claus},
                    {first:John,last:Doe},
                    {first:Jane,last:Johnson}];

  // displaying the items to FF console,
  // open your console and click on the object and hit options to see
  the parameters
  Start ={
          init:function(people){
                  people.each(function(obj,count){
                          //this shows looping through the array correctly
                          Start.log(obj);
                          //in theory this should be showing the class with 
  each array item
  instead it s storing the last item
                          Start.log(new Test(count,obj));
                  });
          },
          log:function(message){
                  if(window.console  console.log) console.log(message);
          }

  };

  Start.init(people);

  /*
  console will show something like this

  Object { first=steven,  more...}
  Object { options=Object}   -- click these, notice they dont match
  the object above instead show last item
  Object { first=John, more...}
  Object { options=Object}  -- click these, notice they dont match
  the object above instead show last item
  Object { first=Jane, more...}
  Object { options=Object}  -- click these, notice they dont match
  the object above instead show last item

  Can someone tell me whats wrong here, thanks
  */

-- 
You received this message because you are subscribed to the Google Groups 
Prototype  script.aculo.us group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.