Lastly, an even better optimization: I'll conclude this by showing how to
be used even more specifically like the class I'm trying to implement,
Here's a version where the object itself is the handler, along with it's
target! Therefore returning *new Proxy(this, this)*; as the only line of
the constructor!
class MyClass {
data = {};
constructor() {
return new Proxy(this, this);
}
get(target, prop) {
prop = prop.toString();
console.log(`Getting property: ${prop}`);
if(prop==="toString"){
return this.toString.bind(target);
}
if(prop==='valueOf'){
return this.valueOf.bind(target);
}
if(prop==="Symbol(Symbol.iterator)"){
return this[Symbol.iterator].bind(target);
}
return this.data[prop];
}
set(target, prop, value) {
console.log(`Setting property: ${prop.toString()} to ${value}`);
this.data[prop] = value;
return true;
}
deleteProperty(target, prop) {
console.log(`Deleting property: ${prop.toString()}`);
delete this.data[prop.toString()];
return true;
}
has(target, prop) {
console.log(`Checking property presence: ${prop.toString()}`);
return prop in this.data;
}
valueOf() {
return 'running valueOf: ' + JSON.stringify(this.data);
}
toString() {
return 'running tostring:' + JSON.stringify(this.data);
}
*[Symbol.iterator]() {
for (const key in this.data) {
console.log('called iterator!');
yield [key, this.data[key]];
}
}
}
Hope sharing this will help someone! :D
Félix
On Friday, August 4, 2023 at 9:55:32 PM UTC-4 Félix wrote:
> Oops: corrected the typo in the example!
> class MyClass {
> data = {};
>
> constructor() {
> return new Proxy(this, {
> get(target, prop) {
> prop = prop.toString();
> console.log(`Getting property: ${prop}`);
> if(prop==="toString"){
> return target.toString.bind(target);
> }
> if(prop==='valueOf'){
> return target.valueOf.bind(target);
> }
> if(prop==="Symbol(Symbol.iterator)"){
> return target[Symbol.iterator].bind(target);
> }
> return target.data[prop];
> },
> set(target, prop, value) {
> console.log(`Setting property: ${prop.toString()} to ${value}`);
> target.data[prop] = value;
> return true;
> },
> deleteProperty(target, prop) {
> console.log(`Deleting property: ${prop.toString()}`);
> delete target.data[prop.toString()];
> return true;
> },
> has(target, prop) {
> console.log(`Checking property presence: ${prop.toString()}`);
> return prop in target.data;
> },
> });
> }
>
> valueOf() {
> return 'running valueOf: ' + JSON.stringify(this.data);
> }
> toString() {
> return 'running tostring:' + JSON.stringify(this.data);
> }
>
> *[Symbol.iterator]() {
> for (const key in this.data) {
> console.log('called iterator!');
> yield [key, this.data[key]];
> }
> }
>
> }
>
> const obj = new MyClass();
> obj['key'] = 'value'; // Setting property: key to value
> console.log("testing setting and getting 'key'");
> console.log(obj['key']); // Getting property: key, value
> delete obj['key']; // Deleting property: key
> console.log("deleted, should be false: ")
> console.log('key' in obj); // Checking property presence: key, false
>
> console.log("testing toString ")
> obj['key3'] = 'value1';
> obj['key4'] = 'value2';
> console.log(obj.toString()); // {"key1":"value1","key2":"value2"}
>
> console.log("testing Symbol.iterator");
> for (const [key, value] of obj) {
> console.log(`${key}: ${value}`);
> }
> On Friday, August 4, 2023 at 9:53:24 PM UTC-4 Félix wrote:
>
>> Dunder methods being (unexhaustive list) : *__contains__, __delitem__,
>> __getitem__, __setitem__, __iter__ and __repr__* in my case.
>>
>> Using javascript little-known 'Proxy object', and passing itself as the
>> target, it's possible to implement the equivalent of Leo's
>> SqlitePickleShare class!
>>
>> *simple proof-of-concept below where it just mimics a dummy dict.
>> Customize as needed for other behaviors!*
>>
>> Félix 🚀😊
>>
>> class MyClass {
>> data = {};
>>
>> constructor() {
>> return new Proxy(this, {
>> get(target, prop) {
>> prop = prop.toString();
>> console.log(`Getting property: ${prop}`);
>> if(prop==="toString"){
>> return target.toString.bind(target);
>> }
>> if(prop==='valueOf'){
>> return target.toString.bind(target);
>> }
>> if(prop==="Symbol(Symbol.iterator)"){
>> return target[Symbol.iterator].bind(target);
>> }
>> return target.data[prop];
>> },
>> set(target, prop, value) {
>> console.log(`Setting property: ${prop.toString()} to ${value}`);
>> target.data[prop] = value;
>> return true;
>> },
>> deleteProperty(target, prop) {
>> console.log(`Deleting property: ${prop.toString()}`);
>> delete target.data[prop.toString()];
>> return true;
>> },
>> has(target, prop) {
>> console.log(`Checking property presence: ${prop.toString()}`);
>> return prop in target.data;
>> },
>> });
>> }
>>
>> valueOf() {
>> return 'running valueOf: ' + JSON.stringify(this.data);
>> }
>> toString() {
>> return 'running tostring:' + JSON.stringify(this.data);
>> }
>>
>> *[Symbol.iterator]() {
>> for (const key in this.data) {
>> console.log('called iterator!');
>> yield [key, this.data[key]];
>> }
>> }
>>
>> }
>>
>> const obj = new MyClass();
>> obj['key'] = 'value'; // Setting property: key to value
>> console.log("testing setting and getting 'key'");
>> console.log(obj['key']); // Getting property: key, value
>> delete obj['key']; // Deleting property: key
>> console.log("deleted, should be false: ")
>> console.log('key' in obj); // Checking property presence: key, false
>>
>> console.log("testing toString ")
>> obj['key3'] = 'value1';
>> obj['key4'] = 'value2';
>> console.log(obj.toString()); // {"key1":"value1","key2":"value2"}
>>
>> console.log("testing Symbol.iterator");
>> for (const [key, value] of obj) {
>> console.log(`${key}: ${value}`);
>> }
>>
>
--
You received this message because you are subscribed to the Google Groups
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/leo-editor/98716f83-50f4-419d-97c7-ae6a27a4f872n%40googlegroups.com.