Re: WebIDL extension proposal for [Enumerable] interface attribute

Hi Anselm.

Anselm R Garbe:
> For example, we are using a Map-like object that exposes file metadata
> which differs among different files (eg an MP3 file has totally
> different metadata than an executable), but the metadata might also
> contain commonly used attributes like the file size or creation date.
> Our current approach to this problem is to declare
> 
> typedef Object Map;
> 
> and using the Map type for these occasions with an informal
> documentation of the actual Map attributes and their values. However,
> we'd like to achieve a more formal way to do so.
> 
> That's why we propose the introduction of an extended interface
> attribute called [Enumerable] into WebIDL and the introduction of the
> extended attribute [Optional] for interface attributes. Given the
> example of file metadata, such a map could be specified as follows:
> 
> [Enumerable] interface FileMetadata {
>   [Optional] attribute long size;
>   [Optional] attribute Date creation;
>   [Optional] attribute Date modification;
> };
> 
> A generic Map-like interface that has no defined optional attributes
> could look like:
> 
> [Enumerable] interface Map {};
> 
> What is your point of view?

I think you should define this instead using named properties.  It
doesn’t seem to be useful to define an interface that has attributes
with particular names and types if they might not exist at all (or might
exist but be different types).

  http://dev.w3.org/2006/webapi/WebIDL/#idl-named-properties

Using the new syntax, I would write:

  interface FileMetadata {
    omittable getter any getProperty(in DOMString propertyName);
    omittable setter void setProperty(in DOMString propertyName,
                                      in any value);
  };

And then, assuming you already define a set of <key,value> pairs
associated with a FileMetadata object that represents the file’s
metadata:

  The supported property names of a FileMetadata object are the keys
  in the set of <key,value> pairs for that object.

And define what the getProperty() and setProperty() operations do:

  When the getProperty(propertyName) operation is called, it must return
  the the value of the <key,value> pair for the object where the key is
  /propertyName/, or null if there is no such pair.

Since it is declared to be omittable, there is no property "getProperty"
or "setProperty" in a FileMetadata object’s prototype chain.  They are
invoked only using [[Get]] and [[Put]] on the object.  So:

  var m = getFileMetadata();
  m.abc;        // Like calling getProperty("abc").
  m.def = 123;  // Like calling setProperty("def", 123).
  m.toString;   // This gets the value of the "toString" property from
                // the Object.prototype object.

In another language binding that doesn’t support object indexing like
this, the operations would correspond to methods, e.g. in Java the
interface would be:

  interface FileMetadata {
    Object getProperty(String propertyName);
    void setProperty(String propertyName, Object value);
  }

If you have properties that aren’t optional, then you can define them as
attributes on the interface:

  interface FileMetadata {
    attribute DOMString filename;

    omittable getter any getProperty(in DOMString propertyName);
    omittable setter void setProperty(in DOMString propertyName,
                                      in any value);
  };

and when you do m.filename, it will get that attribute’s value rather
than invoke the getter operation.


What this doesn’t get you, and which maybe I’ll add some Web IDL support
for, is allowing named properties to have different types.  The host
object [[Put]] method 

  http://dev.w3.org/2006/webapi/WebIDL/#put

doesn’t deal with converting the ECMAScript value to an IDL value, but
it should convert the assigned ECMAScript value to the IDL type of the
setter operation’s second argument.  Maybe I should allow specs to hook
in to say what type to convert the assigned ECMAScript value to, e.g.
just with prose:

  The type of the FileMetadata named property "size" is long.

That then would invoke the “convert ECMAScript value to an IDL long”
algorithm from the host object [[Put]] method.


The other thing it doesn’t get you is enumerability of the properties.
Currently any corresponding named properties (i.e., properties that
exist on the host object that correspond to a supported named property)
are DontEnum.  I can add an extended attribute, say
[NamedPropertiesEnumerable], for this.

-- 
Cameron McCormack ≝ http://mcc.id.au/

Received on Thursday, 2 July 2009 02:00:15 UTC