プロパティ宣言の自動サポートを追加しようとしています。そのため、クラスで自動的にgetterとsetterが生成されます。私は中間クラスライブラリをクラスのベースとして使用します。私はプロパティの作成を扱うルートクラスを定義しました。しかし、テストでは、ルートクラスの直下のサブクラスだけが適切に動作します。他の私はスタッククラスオーバーフローエラー深い中クラスコード([string "local middleclass = {..."]:82: stack overflow
)を与える。middleclass:プロパティのgetter-setterサポートを追加する
私のコードは次のとおりです。
local CBaseObject=class('CObjectBase');
function CBaseObject:initialize()
self._init=true;
end;
function CBaseObject:finalize()
self._init=false;
end;
function CBaseObject:_getter_setter(v)
return v;
end;
function CBaseObject:_gen_prop_cache()
rawset(self,'_properties',rawget(self,'_properties') or {});
end;
function CBaseObject:__index(k)
print('GET',k);
self:_gen_prop_cache();
local prop=self._properties[k];
if prop~=nil
then
local getter=self[prop[2] or '_getter_setter'];
return getter(self,prop[1]);
else return nil;end;
end;
function CBaseObject:__newindex(k,v)
print('ME',self.class.name);
print('SET',k,v);
self:_gen_prop_cache();
local prop=self._properties[k];
if prop==nil and self._init or prop
then
if prop==nil then prop={};self._properties[k]=prop;end;
local vv=prop[1];
if type(v)=='table' and #v<4
then
for i=1,3 do prop[i]=v[i];end;
else
prop[1]=v;
end;
local setter=self[prop[3] or '_getter_setter'];
prop[1]=setter(self,prop[1],vv);
else
rawset(self,k,v);
end;
end;
テストクラス:
local cls=CBaseObject:subclass('test');
function cls:initialize()
self.class.super.initialize(self);
self.health={1000,'_gethealth','_sethealth'};
self.ammo=100;
self:finalize();
end;
function cls:_sethealth(value,old)
print('WRITE:',value,old);
if value<0 then return old;else return value;end;
end;
function cls:_gethealth(value)
print('READ:',value);
return value/1000;
end;
local cls2=cls:subclass('test2');
function cls2:initialize()
self.class.super.initialize(self);
self.ammo=200;
self:finalize();
end;
function cls2:_sethealth(value,old)
print('WRITE_OVERRIDEN:',value,old);
return value;
end;
local obj=cls2(); --change this to cls() for working example.
obj.health=100;
obj.health=-100;
print(obj.health,obj._properties.health[1]);
print(obj.ammo,obj._properties.ammo[1]);
私は自分のコードを実行するためにhttps://repl.it/languages/luaを使用しました。それで、質問は、私が正しいアプローチでさえもやっていることですか?使用しているライブラリと互換性のある簡単な方法でプロパティサポートを追加することは可能ですか?それとも、私は別のものを使うべきですか?
EDIT:実験した後、私は構造体self.class.parent.<method>(<...>)
がエラーの原因であることを知りました。私はそのような出来事をすべて実際の親クラスで置き換えました。これが唯一の問題でした。それ以降、コードはこれまでのところエラーフリーで動作するようになりました。
あなた自身であなたの質問に答えることができます、それに答える、質問を編集しないでください...あなたはセミコロンbtwを削除することができます。彼らはLuaでは必要ではありません。 – Piglet
でも、私がやったことがもっとうまくいくかどうかは分かりません。私は他の言語で私の習慣を台無しにしたくないので、私はセミコロンに固執します。 – ZzZombo