Author Topic: [Resource] Get or set an arbitrary object attribute (by string) without eval()  (Read 2079 times)

This resource adds getAttribute(string attr) and setAttribute(string attr, value) methods to all objects.
Neither of these use slow eval() (thus also not requiring identifier syntax checking) or are prone to injection.

==>$a = new ScriptObject();
==>$a.setAttribute("foo bar", 123);
==>$a.dump();
Member Fields:
Tagged Fields:
  foo bar = "123"
Methods:
  ...
==>echo($a.getAttribute("foo bar"));
123
==>$a.test = "xyz";
==>$a.x[5] = 127;
==>echo($a.getAttribute("test"));
xyz
==>echo($a.getAttribute("x5"));
127
==>echo($a.unexistantAttr $= $a.getAttribute("unexistantAttr"));
1


The crazy switches are worth it, believe me.



Copy from below, or use this Gist.

function SimObject::getAttribute(%this, %attr)
{
   if (%attr $= "")
      return "";

   switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%attr, 0, 1)))
   {
      case  0: return %this._[getSubStr(%attr, 1, strlen(%attr))];
      case  1: return %this.a[getSubStr(%attr, 1, strlen(%attr))];
      case  2: return %this.b[getSubStr(%attr, 1, strlen(%attr))];
      case  3: return %this.c[getSubStr(%attr, 1, strlen(%attr))];
      case  4: return %this.d[getSubStr(%attr, 1, strlen(%attr))];
      case  5: return %this.e[getSubStr(%attr, 1, strlen(%attr))];
      case  6: return %this.f[getSubStr(%attr, 1, strlen(%attr))];
      case  7: return %this.g[getSubStr(%attr, 1, strlen(%attr))];
      case  8: return %this.h[getSubStr(%attr, 1, strlen(%attr))];
      case  9: return %this.i[getSubStr(%attr, 1, strlen(%attr))];
      case 10: return %this.j[getSubStr(%attr, 1, strlen(%attr))];
      case 11: return %this.k[getSubStr(%attr, 1, strlen(%attr))];
      case 12: return %this.l[getSubStr(%attr, 1, strlen(%attr))];
      case 13: return %this.m[getSubStr(%attr, 1, strlen(%attr))];
      case 14: return %this.n[getSubStr(%attr, 1, strlen(%attr))];
      case 15: return %this.o[getSubStr(%attr, 1, strlen(%attr))];
      case 16: return %this.p[getSubStr(%attr, 1, strlen(%attr))];
      case 17: return %this.q[getSubStr(%attr, 1, strlen(%attr))];
      case 18: return %this.r[getSubStr(%attr, 1, strlen(%attr))];
      case 19: return %this.s[getSubStr(%attr, 1, strlen(%attr))];
      case 20: return %this.t[getSubStr(%attr, 1, strlen(%attr))];
      case 21: return %this.u[getSubStr(%attr, 1, strlen(%attr))];
      case 22: return %this.v[getSubStr(%attr, 1, strlen(%attr))];
      case 23: return %this.w[getSubStr(%attr, 1, strlen(%attr))];
      case 24: return %this.x[getSubStr(%attr, 1, strlen(%attr))];
      case 25: return %this.y[getSubStr(%attr, 1, strlen(%attr))];
      case 26: return %this.z[getSubStr(%attr, 1, strlen(%attr))];
   }

   return "";
}

function SimObject::setAttribute(%this, %attr, %value)
{
   if (%attr $= "")
      return;

   switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%attr, 0, 1)))
   {
      case  0: %this._[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  1: %this.a[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  2: %this.b[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  3: %this.c[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  4: %this.d[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  5: %this.e[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  6: %this.f[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  7: %this.g[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  8: %this.h[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case  9: %this.i[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 10: %this.j[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 11: %this.k[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 12: %this.l[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 13: %this.m[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 14: %this.n[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 15: %this.o[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 16: %this.p[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 17: %this.q[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 18: %this.r[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 19: %this.s[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 20: %this.t[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 21: %this.u[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 22: %this.v[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 23: %this.w[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 24: %this.x[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 25: %this.y[getSubStr(%attr, 1, strlen(%attr))] = %value;
      case 26: %this.z[getSubStr(%attr, 1, strlen(%attr))] = %value;
   }
}

Heh, that's a pretty smart way of doing it..

gotta love how arrays work

That's a pretty unique way to do it. Thanks!

stripos is not a default function, though.
« Last Edit: October 29, 2014, 04:37:23 PM by Greek2me »


That's a pretty unique way to do it. Thanks!

stripos is not a default function, though.

stripos is a function provided by the engine.

stripos seems to be added by badspot because 1). I can't find it in tge source and 2). trace(1); stripos(something); doesn't tell me anything

stripos seems to be added by badspot because 1). I can't find it in tge source and 2). trace(1); stripos(something); doesn't tell me anything

trace only shows functions defined in TorqueScript though? Regardless, the point is that it's always available in Blockland.

trace only shows functions defined in TorqueScript though? Regardless, the point is that it's always available in Blockland.

"is stripos a default engine func for Blockland?"

test #1: does calling it work on a fresh install?

yes.

test #2: could it be a script function?

for script functions, trace prints out extended information. using trace here yeilded no such information.

test #3: is it inside the tge source?

no.

conclusion: stripos is an engine func that's not found in stock tge. in other words, badspot added it himself.

I should've said "trace(1); stripos(something); doesn't give me anything that trace would normally give for a script function"

Nice. Must've been a recent change. I'm dumb
« Last Edit: October 29, 2014, 04:37:13 PM by Greek2me »

Nice. Must've been a recent change.
I can't tell you how long ago I dumped the console but it's right there in it.
Quote
   /*!  Find needle in hay, starting offset bytes in. */
   virtual int strpos(string hay, string needle, int offset=0) {}
   /*!  Find needle in hay, starting offset bytes in. (Case insensitive) */
   virtual int stripos(string hay, string needle, int offset=0) {}

Err, I was thinking of striReplace.