Hey Jesse,

Interesting idea here -- this sounds suspiciously akin to the functionality
already present in exportJs(...) used for exporting symbols. This method
upserts the namespace in much the same way as your helper method does.
Thoughts on whether we could reuse or augment that?

-j

On Thu, Jul 28, 2011 at 7:52 AM, Ciancetta, Jesse E. <jc...@mitre.org>wrote:

> I agree with John -- I also prefer the first style Paul presented (which I
> believe is also the most prevalent style in Shindig currently).
>
> With respect to the issues that Michael raised about building up a
> namespace from across different files -- this got me thinking about a little
> namespace utility a colleague of mine wrote a while back.  That utility just
> took a target namespace like "shindig.util.foo", created an empty object in
> it (without clobbering any parts of the target namespace that may have
> already existed) and returned it -- so you could then do something like
> shindig.util.foo.x = ... directly without needing to create each piece of
> the namespace manually.
>
> And with some (well, a lot) of tweaking I was able to turn that function
> into a more general purpose namespacing function that takes an optional
> object to place into the target namespace -- and if the target namespace
> already exists it takes the properties of the optional object and appends
> them to the existing namespace.
>
> So I think if enough people preferred the first style Paul presented,
> something like this could be used to work around the issues Michael raised.
>  Here is the function and some sample usages (with the caveat that I haven’t
> actually used this for anything real so there could be some bugs in it):
>
> var shindig = shindig || (function() {
>    var namespace = function(targetNamespace, optObject) {
>        //get a reference to the global window object
>        var object = window;
>
>        //if no object was provided to put into the namespace create an
> empty one
>        optObject = optObject || {};
>
>        //split the namespace into its parts
>        var namespaces = targetNamespace.split(".");
>
>        //for each part of the namespace
>        for (var i = 0; i < namespaces.length; i++) {
>            //see if this part is already defined
>            if (typeof object[namespaces[i]] === "undefined") {
>                //if its not defined already -- put an object into it
>                //if we're at the end of the targetNamespace, put the new
> object into it,
>                //otherwise drop in an empty object as a placeholder
>                object[namespaces[i]] = (i + 1) == namespaces.length ?
> optObject : {};
>            } else {
>                //there is already something here -- see if we're at the end
> of the targetNamespace
>                if ((i + 1) == namespaces.length) {
>                    //make sure its an object we can append to
>                    if (typeof object[namespaces[i]] === "object") {
>                        //go ahead and add all the public properties on
> optObject to the target namespace
>                        for (var property in optObject) {
>                            object[namespaces[i]][property] =
> optObject[property];
>                        }
>                    } else {
>                        throw "Cannot append new properties to object of
> type " + typeof object[namespaces[i]];
>                    }
>                }
>            }
>
>            object = object[namespaces[i]];
>        }
>
>        return object;
>    };
>
>    return {
>        namespace: namespace
>    };
> })();
>
> //could be from foo-utils.js
> shindig.namespace("shindig.util", (function() {
>    var privateData = "this is private";
>
>    var privateFunction = function() {
>        console.log(privateData);
>    };
>
>    var calculateFoo = function() {
>        privateFunction();
>    };
>
>    var doAlotOfFoo = function() {
>        //do alot of foo
>    };
>
>    return {
>        calculateFoo: calculateFoo,
>        doAlotOfFoo: doAlotOfFoo
>    };
> })());
>
> //could be from bar-utils.js
> shindig.namespace("shindig.util", (function() {
>    var privateFunction = function() {
>        console.log("calculateBar called");
>    };
>
>    var calculateBar = function() {
>        privateFunction();
>    };
>
>    return {
>        publicData: "this is public",
>        calculateBar: calculateBar
>    };
> })());
>
> shindig.namespace("shindig.some.emptyNamespace");
> shindig.some.emptyNamespace.xyz = "ABC";
>
> >-----Original Message-----
> >From: Michael Hermanto [mailto:mherma...@gmail.com]
> >Sent: Tuesday, July 26, 2011 6:15 PM
> >To: dev@shindig.apache.org
> >Subject: Re: javascript readability..
> >
> >What didn't work for me with --
> >   shindig.foo = function() {
> >     return { 'bar': ... };
> >   }();
> >... is that methods in the same namespace have to be all
> >defined/implemented
> >in one file.
> >
> >ie: it's fine if all gadgets.rpc.* is implemented in a file rpc.js, but
> not
> >fine when gadgets.util.* are implemented across different files/features
> >across core.util.dom, core.util.string, etc. When feature core.util pulls
> >all these files in, it will effectively stomp all the previously-defined
> >core.util.*.
> >
> >The tendency has been to make libraries smaller and more focussed to what
> >they do, ie: this means breaking up features into sub-features. To do so,
> I
> >had to convert more-focussed core.util.[dom|string|...] to fully-defined
> >names. Unless the above style (with shindig.foo) doesn't have this
> >limitation (ie: can incrementally define more methods on top what has been
> >defined), I personally prefer the fully-defined names, for consistency.
> >
> >
> >
> >2011/7/26 ๏̯͡๏ Jasvir Nagra <jas...@google.com>
> >
> >> I don't have a strong preference either way although it's nice when
> >> reviewing code to have all the exported things exported once when they
> >> share
> >> a scope full of private helpers and other state.  It also helps convey
> when
> >> the setup of a particular part of the object graph is done.
> >> Eg.
> >>
> >> shindig.foo = (function() {
> >>  // ... all the helper functions and shared state ...
> >>  ...
> >>  return { bar: bar, baz: baz };
> >> }();
> >> // at this point I know from convention that shindig.foo is done being
> >> setup
> >> and will have just "bar" and "baz"
> >>
> >> vs.
> >>
> >> shindig.foo.bar = function() { ... }
> >> /// ... a lot of code later
> >> shindig.foo.baz = function() { ... }
> >>
> >> If the amount of code between shindig.foo and the return is long, I'd
> >> suggest another alternative that I think has the advantage of both:
> >>
> >> (function() {
> >>  // ... all the helper functions and shared state ...
> >>
> >>  shindig.foo = {
> >>    bar: bar,
> >>    baz: baz
> >>  }
> >> })();
> >>
> >> On Tue, Jul 26, 2011 at 2:19 PM, John Hjelmstad <fa...@google.com>
> >wrote:
> >>
> >> > With the model we're using with exportJs, you actually can't as easily
> do
> >> > that or wrap "singleton"/namespaced items, unless you . exportJs(...)
> is
> >> > injected after the closure.
> >> >
> >> > function() {
> >> >  foo.bar.baz = function() { }
> >> > }();
> >> > exportJs("foo.bar", [foo,foo.bar], {baz:"baz"});
> >> >
> >> > Of course, you can if you also update the style guide to prepend
> window:
> >> >
> >> > function() {
> >> >  window.foo.bar.baz = function() { }
> >> > }();
> >> >
> >> > ...though that requirement seems a little awkward and verbose to me.
> >> >
> >> > --j
> >> >
> >> > On Tue, Jul 26, 2011 at 2:12 PM, Dan Dumont <ddum...@us.ibm.com>
> >wrote:
> >> >
> >> > > As mentioned by Paul before you can define:
> >> > >
> >> > > function(){
> >> > >   FooClass.prototype.method = function() { }
> >> > >  FooClass.prototype.method2 = function() { }
> >> > > }();
> >> > >
> >> > > to get a local scope.
> >> > >
> >> > > I think this makes it easier to audit what must be included in an
> >> export.
> >> > > And when you come up for air soon, maybe we can talk about AMD
> >format
> >> and
> >> > > what that brings to the table.  :)
> >> > >
> >> > >
> >> > >
> >> > > From:   John Hjelmstad <fa...@google.com>
> >> > > To:     dev@shindig.apache.org,
> >> > > Date:   07/26/2011 04:43 PM
> >> > > Subject:        Re: javascript readability..
> >> > >
> >> > >
> >> > >
> >> > > I still prefer status quo, as it reads more like a proper class to
> me,
> >> > > while
> >> > > being less verbose and centralizing the exported method definitions
> in
> >> a
> >> > > single place.
> >> > >
> >> > > As well, this question's corollary is whether to convert all
> >> instantiable
> >> > > objects to the form:
> >> > >
> >> > > FooClass.prototype.method = function() { }
> >> > > FooClass.prototype.method2 = function() { }
> >> > >
> >> > > ...from:
> >> > > FooClass = function() {
> >> > >  // private state
> >> > >  function method() { }
> >> > >  function method2() { }
> >> > >  return {
> >> > >    method: method,
> >> > >    method2: method2
> >> > >  };
> >> > > };
> >> > >
> >> > > On this note, I'm conflicted. I like having actual private state,
> but
> >> > > prototype-style is more efficient.
> >> > >
> >> > > Enough people have complained over time about each of the existing
> >> idioms
> >> > > though that I suppose I could go the other direction, if it's
> causing
> >> > > development trouble.
> >> > >
> >> > > --j
> >> > >
> >> > > On Tue, Jul 26, 2011 at 6:17 AM, Ryan J Baxter <rjbax...@us.ibm.com
> >
> >> > > wrote:
> >> > >
> >> > > > +1 As well, I think its easier to read.
> >> > > >
> >> > > > -Ryan
> >> > > >
> >> > > > Email: rjbax...@us.ibm.com
> >> > > > Phone: 978-899-3041
> >> > > > developerWorks Profile
> >> > > >
> >> > > >
> >> > > >
> >> > > > From:   Dan Dumont/Westford/IBM@Lotus
> >> > > > To:     dev@shindig.apache.org,
> >> > > > Date:   07/26/2011 09:00 AM
> >> > > > Subject:        Re: javascript readability..
> >> > > >
> >> > > >
> >> > > >
> >> > > > +1
> >> > > >
> >> > > >
> >> > > >
> >> > > > From:   Paul Lindner <lind...@inuus.com>
> >> > > > To:     dev@shindig.apache.org,
> >> > > > Date:   07/26/2011 02:51 AM
> >> > > > Subject:        javascript readability..
> >> > > >
> >> > > >
> >> > > >
> >> > > > Hi,
> >> > > >
> >> > > > I'm curious to know what people think about some of the idioms in
> the
> >> > JS
> >> > > > code you find in shindig.  There's an awful lot of stuff like
> this:
> >> > > >
> >> > > > shindig.foo = function(){
> >> > > >  //...
> >> > > >  var myFunction = function() {
> >> > > >     }
> >> > > >
> >> > > >  return {'foo': myFunction,
> >> > > >            'bar': function() {
> >> > > >               return 'bar';
> >> > > >            }};
> >> > > > }();
> >> > > >
> >> > > >
> >> > > > Just search for @member to see the various places.
> >> > > >
> >> > > > What would people think if we moved to fully defined names for
> >> > > > function/method definitions instead?
> >> > > >
> >> > > > You could still wrap this inside a closure if you wanted local
> scope:
> >> > > >
> >> > > > function() {
> >> > > >  shindig.foo.foo = function() {
> >> > > >     ...
> >> > > >  }
> >> > > >  shindig.foo.bar = function() {
> >> > > >     ...
> >> > > >  }
> >> > > > }();
> >> > > >
> >> > > > --
> >> > > > Paul Lindner -- lind...@inuus.com -- linkedin.com/in/plindner
> >> > > >
> >> > > >
> >> > > >
> >> > > >
> >> > > >
> >> > > >
> >> > > >
> >> > >
> >> > >
> >> > >
> >> > >
> >> >
> >>
>

Reply via email to