### Answer to Bemi Faison ###

> I'm definitely late to this thread, but isn't this what the ES5 Proxy object 
> is all about?
Didn't know that thing existed O_O
But it doesn't see like finished...
I'll digg into it and see if I can make my API so that it is possible
to get from one to the other. This way I would allow writing code with
that API and it would be compiled to my API so that old browsers get
it.
But I hope it won't be as slow as native getters / setters...
http://jsperf.com/native-getters-vs-function-getters/3

> Even the ES5 Object constructor lets you handle non-mapped properties.
I didn't understand what you mean by non-mapped...
You mean having a default getter?

> Also, JavaScript 1.8.1 (available since FireFox 3.5) lets you define getters 
> and setters for properties - such that assignments (via "=") actually pass 
> arguments to an internal setter function.
It's slow... And can't be emulated on IE.

> Without these, you would need to use closures and use an access schema within 
> your get/set functions. The caveat with this non-native approach, is that 
> developers would need to learn your table schema, or the API for defining it 
> (as you have already). If I'm off, then pardon me and continue your 
> discussion...
My API isn't that hard :o

> If I'm right, then check out my previous work, GSet, at 
> https://github.com/bemson/GSet/ . (It was formally called Proxy, until I 
> discovered the ES5 Proxy object.) My approach differs from yours, in that my 
> object is compiled (i.e., cannot be changed). XJSAccessors.js lets the 
> developer change the access scheme of an object dynamically. Thus, I use a 
> configuration object, while you have an API. On the subject of what to name 
> getters and setters, I chose to follow jQuery's same-name approach.

Well I prefer mine :-*
And I don't like the jQuery approach for getters / setters because
having the same function as getters and setter seems strange to me.
You have to do the exact same condition in every single function...
and you can't have a default setter / getter.

> One last note: I'm phasing out my own use of GSet, as it's numerous closures 
> actually degrade performance.
Obviously but unless you loop on the object, i can't be that much.
You just need to store the value in a local variable when using the
object from outside.
And I'm thinking of "compiling" my code so that for "public" (with no
getter or setter and not readonly / protected) properties, it gets
back to the normal thing.
But I'll see that later. I want my code to work as is. If i can be
compiled to be faster, why not :)

On Fri, Sep 2, 2011 at 2:09 PM, Xavier MONTILLET
<[email protected]> wrote:
> ### Answer to Scott Sauyet ###
>
>> If my object is a dumb data container with no behavior, then I probably want 
>> direct access to its properties
> Well the syntax is a bit longer but you have, kind of, direct access...
>
>> Perhaps I don't care if it's calculated, read-only, or normal.  But perhaps 
>> I do.
> I don't see any cases where you want to know whether it is calculated or 
> not...
>
>> I certainly don't want to have to wrap a try-catch around setting the 
>> property on the off-chance it might be read-only.
> - When you build your API: As the thing that lets you change getters /
> setters is local to the constructor, it can't be used by other code
> (except if you don't get the point at all and expose it...) so as you
> decide what is readonly and what is not.
> - When you use an API: You'll use a property and if you get an error,
> it'll be during development. I thought about failing silently but
> then, you wouldn't know if your value was set or not. Here, you know
> either it is set or you get an error because it is readonly. I mean as
> it is either readonly or not but won't change, you know that if you
> get the error you will never be allowed to write... I'm not sure I'
> clear. Please tell me if I am not.
>
>> And I don't want to have to do a for-in just to find out what features my 
>> object supports, at least not when its design is something already in my 
>> control.
> Well that's what the documentation is for... If you have a "normal"
> object, you get to for in it to see what's in...
> E.g.: PhantomJS. This thing is awesome but the documentation sucks.
> Well I used for in of the page object and the phantom object to see
> what properties I had... even though they use a "normal" API.
>
>> There are new language features creeping in that will allow us to do 
>> C#-style setters and getters, but I've almost never had a need for them in 
>> Javascript.
> Well the first thing is native getters are way too slow:
> http://jsperf.com/native-getters-vs-function-getters/3
> Plus they don't work in IE.
> And there is nothing to get any property.
> If you want to emulate an array, you can't or you would need to set
> getters and setters for 0, 1, 2, 3, 4...
> There is no such thing as object.__defineGetter__( '*', f ); In fact
> this works but for the '*' property... whereas you would want it to be
> the getter for all properties you don't know. I'm planning on
> implementing that too in my getters / setters: A default getter /
> setter.
>
>>But I simply can't see the advantage of turning this:
>>
>>   myRectangle.height = 3;
>>   myRectangle.width = 5;
>>   var area = myRectangle.getArea();
>>
>>into this:
>>
>>   myRectancle.set("height", 3");
>>   myRectancle.set("width", 3");
>>   var area = myRectangle.get("area");
>>
>>I can't even buy that the latter would be better than
>>
>>   myRectangle.setHeight(3);
>>   myRectangle.setWidth (5);
>>   var area = myRectangle.getArea();
> For the first code, the problem is you need to know what property can
> only be set by a function and what property can be set "normaly".
> For the third code, the problem is that cycling though the object is a
> pain (it is in first too) and if you want to implement a default
> getter / setter, you can't use that syntax. Plus for some reason, I
> don't like it.
>
>> Have you thought through how you might document your API?  I love tools like 
>> JSDoc, but can't see how to use anything like it with your code.  Do you 
>> have other ideas?
> Well in fact, you can use any tool... You just need to put a page that
> explains how the API works and let the others that describe properties
> as they are.
> But that won't come before I judge my code is "usable".
>
>> I'm not sure it's a matter of caring.  It's a matter of what facilities the 
>> language provides, and what glosses you are trying to provide.  You seem to 
>> be promoting something that to me makes it less clear what's going on.  I 
>> understand that you don't see it that way, but having an object with only 
>> three properties, the functions `get`, `set`, and `forIn` just confuses 
>> things for me.
>
> Well just think as if o.set( 'p', 'v' ) was o.p = 'v' and o.get( 'p' ) was o.p
> And o.forIn( function ( name ) { } ) is for ( var name in o ) {}
> I might also update set to accept this syntax:
>
> o.set( {
>    p: 'v',
>    p2: 'v2'
> } );
>
>> When myRectangle has numeric properties `height` and `width` and a function 
>> `getArea`, I have a pretty good idea how to use it.  If myRectangle exposes 
>> `get`, `set`, and `forIn`, which is the same API exposed by mySpaceship and 
>> myHttpRequest, I'm really not certain how to use any of them.
> Except for that one time with PhantomJS, I never looked directly the
> API on the object... everything has a documentation...
> But I could also add a getAll method on the object that uses the forIn
> to loop through all properties and creates a new object containing all
> the values it got. It would let you explore it easily.
>
>>I don't think it's that they don't care what it does, but that they don't 
>>care how it does it.  But speaking of jQuery, could you imagine a version of 
>>it using your Accessors?  What would it look like for a jQuery wrapped 
>>object?  How would the `.data()` function be structured?  How about 
>>`.addClass()`  or `.attr()`?  Or it's not a candidate for using your tool, 
>>what would distinguish a good candidate?
>
> new XJSElement( element ).get( 'data' ).set( 'property', 'value' );
> XJSElement could be replaced by jQuery if jQuery was building the good 
> methods.
>
> new XJSElement( element ).get( 'class' ).set( 'property', 'value' );
>
> new XJSElement( element ).get( 'attributes' ).set( 'src', 'w/e' );
>
> But of course, you'll also be able to do that:
> new XJSElement( element ).get( ['attributes', 'src'] );
> Or event
> new XJSElement( element ).get( 'attributes', 'src' );
> or
> new XJSElement( element ).get( 'attributes.src' );
> But I'm sot sure about the last one because it disallows getting
> properties whose name contain a point. I've never seen one though.
> And the one before would disallow passing arguments to getters.
>
> It might look a bit long but if you provide a direct data property:
> new XJSElement( element ).data
> it mean you have already built a new instance of the XJSElementData
> constructor and if it is bot used, you lost time.
>
> Another approch would be wrappers / aliases:
> new XJSElement( element ).get( 'data', 'name' );
> new XJSElement( element ).set( 'data', 'name', 'value' );
> Because as you have seen, the getters get all the arguments passed to
> get so they can use some.
> for the getters that would be simple. For the setters, I have to do
> some "router" that will know how many times to use get before using
> set (It might be when it has 2 arguments left but then, composite
> values for setters, i mean setters that get more arguments wouldn't
> work. Same for setters allowing to not define the value and set
> something if it is undefined. ). We'll see.
>
>> That's what I suspected.  I'm curious about the environment you're using 
>> this sort of code in?  It reminds me a bit of the JavaBeans spec -- great 
>> for tooling and other applications where the consumer knew nothing about 
>> your API but just an additional burden for direct consumers who are using 
>> your API semantically.
> Well I never used something like that... In fact I only know HTML,
> CSS, JS, a bit of PHP and the minimum of Python. And shell.
> And I don't see how it could be a burden (except that it's a bit
> longer to write...)
>
>
> On Thu, Sep 1, 2011 at 7:47 PM, Bemi Faison <[email protected]> wrote:
>> I'm definitely late to this thread, but isn't this what the ES5 Proxy object
>> is all about? Even the ES5 Object constructor lets you handle non-mapped
>> properties. Also, JavaScript 1.8.1 (available since FireFox 3.5) lets you
>> define getters and setters for properties - such that assignments (via "=")
>> actually pass arguments to an internal setter function.
>> Without these, you would need to use closures and use an access schema
>> within your get/set functions. The caveat with this non-native approach, is
>> that developers would need to learn your table schema, or the API for
>> defining it (as you have already). If I'm off, then pardon me and continue
>> your discussion...
>> If I'm right, then check out my previous work, GSet, at
>> https://github.com/bemson/GSet/. (It was formally called Proxy, until I
>> discovered the ES5 Proxy object.) My approach differs from yours, in that my
>> object is compiled (i.e., cannot be changed). XJSAccessors.js lets the
>> developer change the access scheme of an object dynamically. Thus, I use a
>> configuration object, while you have an API. On the subject of what to name
>> getters and setters, I chose to follow jQuery's same-name approach.
>> As an example, here's how you would use GSet to configure getters, setters,
>> and "calculators".
>> /example------------------------------
>> var mySquare = new GSet(
>>   {myWidth:4, myLength:2}, // original/protected object
>>   { // access scheme
>>     width: ['myWidth', 'number'],
>>     length: ['myLength', 'number'],
>>     area: [
>>       function () {
>>         return this.myWidth * this.myLength;
>>       },
>>       'number',
>>       function (w, l) {
>>         if (arguments.length > 1) {
>>           this.myWidth = w;
>>           this.myLength = l;
>>         } else {
>>           return false;
>>         }
>>       }
>>     ]
>>   }
>> );
>> mySquare.width(2); // true
>> mySquare.width(); // 2
>> mySquare,width('foo'); // false
>> mySquare.area(); // 4
>> mySquare.area(10,10); // true
>> mySquare.area(); // 100
>> ------------------------------example/
>> One last note: I'm phasing out my own use of GSet, as it's numerous closures
>> actually degrade performance.
>> - best,
>> bemson
>>
>> --
>> To view archived discussions from the original JSMentors Mailman list:
>> http://www.mail-archive.com/[email protected]/
>>
>> To search via a non-Google archive, visit here:
>> http://www.mail-archive.com/[email protected]/
>>
>> To unsubscribe from this group, send email to
>> [email protected]
>>
>

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to