### 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