FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

November 9th -- (Runtime) indexing changes, tasty bugfixes

 
Post new topic   Reply to topic     Forum Index -> MiniD
View previous topic :: View next topic  
Author Message
JarrettBillingsley



Joined: 20 Jun 2006
Posts: 457
Location: Pennsylvania!

PostPosted: Thu Nov 09, 2006 11:55 pm    Post subject: November 9th -- (Runtime) indexing changes, tasty bugfixes Reply with quote

Thankfully it's runtime indexing that's been changed, and not compiler indexing. I don't think I can deal with compiler indexing issues anymore.

Fixed
  • When I fixed a bug with too many stack values getting nulled out when entering a function a few releases back, I inadvertently broke it for when not enough parameters were passed to a function. Now unpassed parameters will get null instead of garbage.
  • Delegates were just plain broken for return values, so I reimplemented how they work. They are now implemented much more optimally, and work just as if they were a function in virtually all cases.


Changed
  • Slicing an array no longer duplicates the array data; the new array simply holds a reference into the old array's data.
  • array.slice() no longer creates a new array instance if it is given no index parameters.
  • opIndex and opIndexAssign metamethods are now only tried if the default indexing mechanism fails.
  • If you try to access a nonexistent member of a table, an exception will be thrown.
  • Because of the previous change, it is now illegal to access a nonexistant global.
  • Changed how class and instance fields and methods are stored. Now classes and instances may not have members whose names are not strings.


Added
  • It is now possible to declare methods in tables, in a similar manner to functions. Keep in mind that methods are just functions with an implicit "this" as the first parameter.


The most notable changes are those regarding indexing. Namely, it is now an error to try to access a table key which has not been added to the table. This also changed global lookup; no more inadvertently accessing globals! Except, of course, if you inadvertently assign to a global, that'll still be a problem..

The other indexing change is that opIndex and opIndexAssign are looked up at the correct time -- after it tries to index the given object normally. Because of this, it's now possible to implement properties. Have a look at this, I think it's cool (it's in simple.md as well):

Code:
// A function which lets us define properties for a class.
// The varargs should be a bunch of tables, each with a 'name' field, and 'getter' and/or 'setter' fields.
function mixinProperties(classType, vararg)
{
   classType.mProps = { };
   
   classType.opIndex = function(this, key)
   {
      if(!this.mProps:contains(key))
         throw format(classType, ":opIndex() - Property '?s' does not exist", key);
         
      local prop = this.mProps[key];
      
      if(!prop:contains("getter"))
         throw format(classType, ":opIndex() - Property '?s' has no getter", key);
         
      return prop.getter(this);
   };

   classType.opIndexAssign = function(this, key, value)
   {
      if(!this.mProps:contains(key))
         throw format(classType, ":opIndexAssign() - Property '?s' does not exist", key);
         
      local prop = this.mProps[key];
      
      if(!prop:contains("setter"))
         throw format(classType, ":opIndexAssign() - Property '?s' has no setter", key);
         
      prop.setter(this, value);
   };
   
   foreach(local k, local v; [vararg])
   {
      if(!isTable(v))
         throw "mixinProperties() - properties must be tables";
      
      if(!v:contains("name"))
         throw format("mixinProperties() - property ", k, " has no name");

      if(!v:contains("setter") && !v:contains("getter"))
         throw format("mixinProperties() - property '?s' has no getter or setter", v.name);

      classType.mProps[v.name] = v;
   }
}

// Create a class to test out.
class PropTest
{
   mX = 0;
   mY = 0;
   mName = "";
   
   method constructor(name)
   {
      this.mName = name;
   }
   
   method toString()
   {
      return format("name = '", this.mName, "' x = ", this.mX, " y = ", this.mY);
   }
}

// Mix in the properties.
mixinProperties(
   PropTest,

   {
      name = "x",
      
      method setter(value)
      {
         this.mX = value;
      }
      
      method getter()
      {
         return this.mX;
      }
   },
   
   {
      name = "y",
      
      method setter(value)
      {
         this.mY = value;
      }
      
      method getter()
      {
         return this.mY;
      }
   },

   {
      name = "name",
      
      method getter()
      {
         return this.mName;
      }
   }
);

// Create an instance and try it out.
local p = PropTest("hello");

writefln(p:toString());
p.x = 46;
p.y = 123;
p.x = p.x + p.y;
writefln(p:toString());

// Try to access a nonexistent property.
try
{
   p.name = "crap";
}
catch(e)
{
   writefln("caught: ", e);
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> MiniD All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group