File naming flexibility when using autoload?

16 views
Skip to first unread message

Anthony

unread,
Apr 3, 2012, 11:23:02 AM4/3/12
to jsclas...@googlegroups.com
I'm trying to integrate my code with JS.Packages a little better using James' recent blog post. One thing I'd like to do is use autoload() to manage namespace dependencies for me, since until now I've had to declare my namespaces at the top of each class file to make sure the objects were defined. 

I have it working when I change my filenames to all lowercase with underscores matching camelcase class names, but really I'd like to keep my existing naming stucture, which is camelcase for folders, filenames, and class names. They all match. Is there a way to use autoload like this?

Anthony

unread,
Apr 3, 2012, 11:28:43 AM4/3/12
to jsclas...@googlegroups.com
I should have mentioned I'm talking about this call and getting the require to notice camelCase paths:

autoload(/^(.*)\.[^\.]+$/, {from: '.', require: '$1'});

James Coglan

unread,
Apr 3, 2012, 11:42:35 AM4/3/12
to jsclas...@googlegroups.com
On 3 April 2012 16:23, Anthony <draft...@gmail.com> wrote:
I'm trying to integrate my code with JS.Packages a little better using James' recent blog post. One thing I'd like to do is use autoload() to manage namespace dependencies for me, since until now I've had to declare my namespaces at the top of each class file to make sure the objects were defined. 

I have it working when I change my filenames to all lowercase with underscores matching camelcase class names, but really I'd like to keep my existing naming stucture, which is camelcase for folders, filenames, and class names. They all match. Is there a way to use autoload like this?

No, the transformation is hard-coded. If I make it pluggable, I wonder whether it would be better to make this a global setting, or just override the default on a per-autoload-rule basis. 

Anthony Rowlands

unread,
Apr 3, 2012, 11:45:19 AM4/3/12
to jsclas...@googlegroups.com
I would be happy if I could pass something to autoload that changes the rule. Gives more flexibility that way.

So do you structure all of your projects with lowercase-underscore paths? Or more bluntly, if I want to use autoload right now am I pretty much locked into that structure?

James Coglan

unread,
Apr 3, 2012, 12:13:51 PM4/3/12
to jsclas...@googlegroups.com
On 3 April 2012 16:23, Anthony <draft...@gmail.com> wrote:
I'm trying to integrate my code with JS.Packages a little better using James' recent blog post. One thing I'd like to do is use autoload() to manage namespace dependencies for me, since until now I've had to declare my namespaces at the top of each class file to make sure the objects were defined. 

I have it working when I change my filenames to all lowercase with underscores matching camelcase class names, but really I'd like to keep my existing naming stucture, which is camelcase for folders, filenames, and class names. They all match. Is there a way to use autoload like this?

James Coglan

unread,
Apr 3, 2012, 12:16:47 PM4/3/12
to jsclas...@googlegroups.com
On 3 April 2012 16:45, Anthony Rowlands <draft...@gmail.com> wrote:
So do you structure all of your projects with lowercase-underscore paths? Or more bluntly, if I want to use autoload right now am I pretty much locked into that structure?

Yes, I do, and yes you are. Makes sense for it to be pluggable though. 

Anthony Rowlands

unread,
Apr 6, 2012, 11:18:57 AM4/6/12
to jsclas...@googlegroups.com
One more question here - I have a class named UIComponent. Should the filename be u_i_component.js for this scheme to work? Should I rename it to UiComponent so I can have the filename be ui_component.js?

James Coglan

unread,
Apr 6, 2012, 11:21:14 AM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 16:18, Anthony Rowlands <draft...@gmail.com> wrote:
One more question here - I have a class named UIComponent. Should the filename be u_i_component.js for this scheme to work? Should I rename it to UiComponent so I can have the filename be ui_component.js?

I *think* the rule is that a lowercase letter followed by an uppercase one introduces an underscore. This means:

* UIComponent -> uicomponent.js
* UiComponent -> ui_component.js 

Anthony Rowlands

unread,
Apr 6, 2012, 11:22:20 AM4/6/12
to jsclas...@googlegroups.com
Okay thanks for the quick response, that filename satisfies me =)

Anthony Rowlands

unread,
Apr 6, 2012, 2:17:32 PM4/6/12
to jsclas...@googlegroups.com
Hi James,

I have refactored all my names to match what we've been discussing.

I'm trying to fire everything up again, but the namespace dependencies aren't working. I have a little confusion about mixing autoload() with regular file() calls. Right now at the top of my manifest I have two autoload lines:

    autoload(/^(.*)\.[^\.]+$/, {from: CONTEXT_PATH + '/scripts', require: '$1'});
    autoload(/^(.*)$/, {from: CONTEXT_PATH + '/scripts'});

These are from your blog post. Below this I still have calls to file() for all of my classes - I basically just added those lines to the top of my previously-working manifest and I was hoping it would resolve namespaces for my classes.

So I tried requiring one of my classes, which has 1 dependency. That dependency (it's called MyApp.util.Utils) fails to execute because MyApp is not defined.

Can you give me a little shove in the right direction?

Anthony

James Coglan

unread,
Apr 6, 2012, 2:22:20 PM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 19:17, Anthony Rowlands <draft...@gmail.com> wrote:
I have refactored all my names to match what we've been discussing.

I'm trying to fire everything up again, but the namespace dependencies aren't working. I have a little confusion about mixing autoload() with regular file() calls. Right now at the top of my manifest I have two autoload lines:

    autoload(/^(.*)\.[^\.]+$/, {from: CONTEXT_PATH + '/scripts', require: '$1'});
    autoload(/^(.*)$/, {from: CONTEXT_PATH + '/scripts'});

So I tried requiring one of my classes, which has 1 dependency. That dependency (it's called MyApp.util.Utils) fails to execute because MyApp is not defined.

Can you give me a little shove in the right direction?

I'm not sure just from this info -- could you publish a minimal example with the same problem to GitHub? 

Anthony Rowlands

unread,
Apr 6, 2012, 3:09:43 PM4/6/12
to jsclas...@googlegroups.com
Hey, I am having trouble getting Git set up on this machine. Can I just email it to you?

James Coglan

unread,
Apr 6, 2012, 3:13:18 PM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 20:09, Anthony Rowlands <draft...@gmail.com> wrote:
Hey, I am having trouble getting Git set up on this machine. Can I just email it to you?

Sure -- I just really need some concrete files to play around with :) 

James Coglan

unread,
Apr 6, 2012, 3:33:00 PM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 19:17, Anthony Rowlands <draft...@gmail.com> wrote:
I'm trying to fire everything up again, but the namespace dependencies aren't working. I have a little confusion about mixing autoload() with regular file() calls. Right now at the top of my manifest I have two autoload lines:

    autoload(/^(.*)\.[^\.]+$/, {from: CONTEXT_PATH + '/scripts', require: '$1'});
    autoload(/^(.*)$/, {from: CONTEXT_PATH + '/scripts'});

For the benefit of others following this conversation, here's the complete manifest:

JS.Packages(function() { with(this) {
  autoload(/^(.*)\.[^\.]+$/, {from: './scripts', require: '$1'});
  autoload(/^(.*)$/, {from: './scripts'});
  
  file('./scripts/my_app/util/utils.js')
    .provides('MyApp.util.Utils')
    .requires('JS.Module');
    
  file('./scripts/my_app/ui/uicomponent.js')
    .provides('MyApp.ui.UIComponent')
    .requires('MyApp.util.Utils');
}}); 

What autoload() does is, it essentially defines a template for new packages -- when you call JS.require(), any names that have not been explicitly defined are matched against the autoload() rules, and the first match is used to construct a package definition (as you would using file()) on the fly.

When you use file() to explicitly create a package, the names in its provides() list are not matched against autoload() rules, so the package does not inherit the requires from the autoload.

Instead (and this might be undocumented, aside from my blog post) you can do this:

  pkg('MyApp.util.Utils')
    .requires('JS.Module');
    
  pkg('MyApp.ui.UIComponent')
    .requires('MyApp.util.Utils');

pkg() essentially either finds or creates a new package that provides the named entity. If the package does not yet exist, autoload() is used to generate it. This means you're generating something from autoload() then adding further dependencies to it.

I hope this makes sense -- if it's not intuitive maybe it needs changing.

James Coglan

unread,
Apr 6, 2012, 3:35:36 PM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 20:33, James Coglan <jco...@gmail.com> wrote:
Instead (and this might be undocumented, aside from my blog post) you can do this:

  pkg('MyApp.util.Utils')
    .requires('JS.Module');
    
  pkg('MyApp.ui.UIComponent')
    .requires('MyApp.util.Utils');

It's also worth restating here that hanging dependencies off of containing namespaces is an easy way to make everything in a certain namespace gain that dependency. This is covered in more details in http://blog.jcoglan.com/2012/01/23/organizing-a-project-with-js-packages/ 

Anthony Rowlands

unread,
Apr 6, 2012, 3:43:10 PM4/6/12
to jsclas...@googlegroups.com
Thanks a ton James. That's exactly what I was confused about - mixing dependency information between file() and autoload(). Glad there's a way to do autoloading and then add specific dependencies; I can see this shrinking my huge manifest to just a handful of lines.

James Coglan

unread,
Apr 6, 2012, 3:45:02 PM4/6/12
to jsclas...@googlegroups.com
On 6 April 2012 20:43, Anthony Rowlands <draft...@gmail.com> wrote:
I can see this shrinking my huge manifest to just a handful of lines.

That's the idea :)

autoload() is not as powerful as file() in some ways (e.g. can only have one require on an autoload) but if used effectively while keeping the manifest small, it keeps your codebase quite predictable. I tries to nudge you toward helpfully organized code. 
Reply all
Reply to author
Forward
0 new messages