[ANN] autoloader, version 0.0.2

Discussion in 'Ruby' started by David Masover, Nov 24, 2009.

  1. A couple of handy features to enhance Kernel#autoload.

    Changes since 0.0.1: minor tweaks to the gem, and migrated to gemcutter.

    Question: How do I add a choice of dependencies? Right now, I can use either
    extlib or activesupport for inflections.

    Also: This is my first ever ruby-talk announcement. Someone please tell me if
    I am Doing It Wrong.


    Pasted from the README:


    Features
    ========

    * Fire Kernel#autoload at an entire directory
    * Fire it again at a subdirectory, for namespace'd models


    Motivation/Examples
    ===================

    I was using Ramaze as a web framework, and discovered that the standard Ramaze
    way of loading a directory of files is to slurp them all (with 'acquire'). I
    decided I'd rather use autoload, and not load things I'm not using. But I
    wasn't really looking forward to this:

    autoload :User, 'model/user'
    autoload :Clan, 'model/clan'
    autoload :Item, 'model/item'

    ...ad nauseum. So, the first feature is a shallow, directory-based autoload:

    AutoLoader << 'model'

    Of course, being a pedant, I like to namespace my models. I don't want to
    slurp the entire directory tree. Instead, you can do this:

    class User < MyFavoriteORM::Model
    include AutoLoader
    ...
    end

    Now, all AutoLoaded paths will be searched for a subdirectory called 'user',
    and all files within will be autoloaded. Just as if you'd done:

    User.autoload :Anonymous, 'model/user/anonymous'
    User.autoload :Registered, 'model/user/registered'

    Of course, there's no requirement that you have a base class, or anything of
    the sort. If you just want a namespace, you can always do:

    module MyNamespace; include AutoLoader; end

    And you're done.


    Compatibility
    =============

    Currently, Merb's extlib and Rails' activesupport are supported. It should be
    trivial to interface with other libraries.
     
    David Masover, Nov 24, 2009
    #1
    1. Advertising

  2. 2009/11/24 David Masover <>:
    > A couple of handy features to enhance Kernel#autoload.
    >
    > Changes since 0.0.1: minor tweaks to the gem, and migrated to gemcutter.
    >
    > Question: How do I add a choice of dependencies? Right now, I can use either
    > extlib or activesupport for inflections.
    >
    > Also: This is my first ever ruby-talk announcement. Someone please tell me if
    > I am Doing It Wrong.


    Looks fine to me. But I do wonder how you generate the symbol names
    for autoload files? Basically autoload needs a symbol name and a file
    name. While the file names can be extracted from a directory how do
    you find the symbol name? Maybe users should be able to customize
    that algorithm in order to be able to autoload class "FooBar" from
    file "foobar.rb" or "foo_bar.rb". I would at least add a description
    how you generate the symbol name from the file name.

    Btw, one disadvantage of using a directory glob is that it is far more
    expensive than the standard autoload because the standard autoload
    does not need any file system IO before any file is loaded. Using
    directory globbing on the other hand requires to at least read the
    directory which may slow down startup of a script considerably.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Nov 24, 2009
    #2
    1. Advertising

  3. On Tue, Nov 24, 2009 at 12:34 AM, David Masover <> wrote:
    > A couple of handy features to enhance Kernel#autoload.
    >
    > Changes since 0.0.1: minor tweaks to the gem, and migrated to gemcutter.
    >
    > Question: How do I add a choice of dependencies? Right now, I can use either
    > extlib or activesupport for inflections.


    As far as I know, you can't.

    I've got a similar situation with ri_cal which needs either
    activesupport or tzinfo. I asked about this on the rubygems list and
    alternate dependencies seemed to be something which had come up from
    time to time but hadn't been addressed.

    I just didn't declare either as a dependency and rely on documentation
    to let users know that they need one or the other.


    --
    Rick DeNatale

    Blog: http://talklikeaduck.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
     
    Rick DeNatale, Nov 24, 2009
    #3
  4. On Tuesday 24 November 2009 06:43:20 am Robert Klemme wrote:
    > Looks fine to me. But I do wonder how you generate the symbol names
    > for autoload files? Basically autoload needs a symbol name and a file
    > name. While the file names can be extracted from a directory how do
    > you find the symbol name?


    More or less the same way Rails does, which is why I support these various
    inflection libraries. Basically, I take the file name and munge it so it looks
    like a constant name.

    > Maybe users should be able to customize
    > that algorithm in order to be able to autoload class "FooBar" from
    > file "foobar.rb" or "foo_bar.rb".


    Right now, it's specified to be foo_bar.rb. It uses String#to_const_string
    from extlib, or String#camelize from ActiveSupport. If neither of these are
    loaded, it tries to load extlib, then activesupport/inflector.

    Maybe users should be able to customize it. The idea is, of course, convention
    over configuration. If there's only a single exception (FooBar, for example),
    you could always manually autoload that one file.

    > I would at least add a description
    > how you generate the symbol name from the file name.


    Neither of these are bad ideas.

    If you can think of a way to customize the behavior without overcomplicating
    things, go for it. I'm not motivated, so patches welcome.

    > Btw, one disadvantage of using a directory glob is that it is far more
    > expensive than the standard autoload because the standard autoload
    > does not need any file system IO before any file is loaded. Using
    > directory globbing on the other hand requires to at least read the
    > directory which may slow down startup of a script considerably.


    Except that standard autoload is more work for me, and nearly defeats the
    point. Trading requires for autoloads directly makes things harder to debug
    without making them easier to write -- it _only_ optimizes start time.

    One possibility would be to write a script which attempts to automatically
    generate these autoload statements, but store them statically in a single
    file. The main reason I don't like that is, you've now added a "compile" step
    to a script. It might work as an option, maybe a "development" vs "production"
    mode.

    Another possibility is to override const_missing, but that gets complex fast,
    as Rails shows.

    Also, keep in mind that the directory IO is shallow. That is, if you tell it
    to autoload foo, it won't touch anything in foo/bar. If you create a file
    bar.rb which requires autoload, it will look at foo/bar, but only once Bar is
    autoloaded.

    Thanks for the feedback!
     
    David Masover, Nov 24, 2009
    #4
  5. On 11/24/2009 07:06 PM, David Masover wrote:
    > On Tuesday 24 November 2009 06:43:20 am Robert Klemme wrote:


    >> Btw, one disadvantage of using a directory glob is that it is far more
    >> expensive than the standard autoload because the standard autoload
    >> does not need any file system IO before any file is loaded. Using
    >> directory globbing on the other hand requires to at least read the
    >> directory which may slow down startup of a script considerably.

    >
    > Except that standard autoload is more work for me, and nearly defeats the
    > point. Trading requires for autoloads directly makes things harder to debug
    > without making them easier to write -- it _only_ optimizes start time.


    Yeah, absolutely. If your major goal is to simplify script writing this
    is definitive a good option. I just wanted to point out that the
    convenience comes at a price. :)

    > One possibility would be to write a script which attempts to automatically
    > generate these autoload statements, but store them statically in a single
    > file. The main reason I don't like that is, you've now added a "compile" step
    > to a script. It might work as an option, maybe a "development" vs "production"
    > mode.


    Yeah, ugly.

    > Another possibility is to override const_missing, but that gets complex fast,
    > as Rails shows.
    >
    > Also, keep in mind that the directory IO is shallow. That is, if you tell it
    > to autoload foo, it won't touch anything in foo/bar. If you create a file
    > bar.rb which requires autoload, it will look at foo/bar, but only once Bar is
    > autoloaded.
    >
    > Thanks for the feedback!


    You're welcome! Thanks for taking the time to digest it.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Nov 24, 2009
    #5
  6. On Tuesday 24 November 2009 04:21:03 pm Robert Klemme wrote:
    > On 11/24/2009 07:06 PM, David Masover wrote:
    > > On Tuesday 24 November 2009 06:43:20 am Robert Klemme wrote:
    > >> Btw, one disadvantage of using a directory glob is that it is far more
    > >> expensive than the standard autoload because the standard autoload
    > >> does not need any file system IO before any file is loaded. Using
    > >> directory globbing on the other hand requires to at least read the
    > >> directory which may slow down startup of a script considerably.

    > >
    > > Except that standard autoload is more work for me, and nearly defeats the
    > > point. Trading requires for autoloads directly makes things harder to
    > > debug without making them easier to write -- it _only_ optimizes start
    > > time.

    >
    > Yeah, absolutely. If your major goal is to simplify script writing this
    > is definitive a good option. I just wanted to point out that the
    > convenience comes at a price. :)


    Well, I want a sane balance. I want to optimize start time to where an app
    starts in under a second, versus thirty seconds -- and I think I've done that
    without much additional complexity.

    In other words, I think it's the best of both worlds.

    If I _only_ wanted to simplify script writing, Ramaze has a much simpler
    solution -- they've defined Kernel#acquire, which requires every .rb file in a
    given directory tree. That's easier to write and easier to use, but as an app
    gets bigger, it would get slower.
     
    David Masover, Nov 25, 2009
    #6
  7. I know about some work on merb, it collects depenedencies, then tries to
    load them in diffirent order, and sees which one ends properly, AFAIK
    there's no way to define alternative dependencies
     
    Marcin Raczkowski, Nov 25, 2009
    #7
  8. On 25.11.2009 03:36, David Masover wrote:
    > On Tuesday 24 November 2009 04:21:03 pm Robert Klemme wrote:
    >> On 11/24/2009 07:06 PM, David Masover wrote:
    >>> On Tuesday 24 November 2009 06:43:20 am Robert Klemme wrote:
    >>>> Btw, one disadvantage of using a directory glob is that it is far more
    >>>> expensive than the standard autoload because the standard autoload
    >>>> does not need any file system IO before any file is loaded. Using
    >>>> directory globbing on the other hand requires to at least read the
    >>>> directory which may slow down startup of a script considerably.
    >>> Except that standard autoload is more work for me, and nearly defeats the
    >>> point. Trading requires for autoloads directly makes things harder to
    >>> debug without making them easier to write -- it _only_ optimizes start
    >>> time.

    >> Yeah, absolutely. If your major goal is to simplify script writing this
    >> is definitive a good option. I just wanted to point out that the
    >> convenience comes at a price. :)

    >
    > Well, I want a sane balance.


    Fair enough.

    > I want to optimize start time to where an app
    > starts in under a second, versus thirty seconds -- and I think I've done that
    > without much additional complexity.


    Well, that sounds like a successful optimization operation. :)

    > In other words, I think it's the best of both worlds.
    >
    > If I _only_ wanted to simplify script writing, Ramaze has a much simpler
    > solution -- they've defined Kernel#acquire, which requires every .rb file in a
    > given directory tree. That's easier to write and easier to use, but as an app
    > gets bigger, it would get slower.


    Good pointer! Thanks for sharing.

    Cheers

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Nov 25, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Augustus Fernandis

    Problem with using AutoLoader Module.

    Augustus Fernandis, Nov 13, 2004, in forum: Perl
    Replies:
    2
    Views:
    492
    Augustus
    Nov 15, 2004
  2. Billy N. Patton

    [Fwd: perl AUTOLOADER vs c++]

    Billy N. Patton, Oct 15, 2004, in forum: C++
    Replies:
    1
    Views:
    434
    David Hilsee
    Oct 15, 2004
  3. V Green
    Replies:
    0
    Views:
    932
    V Green
    Feb 5, 2008
  4. PA Bear [MS MVP]
    Replies:
    0
    Views:
    1,044
    PA Bear [MS MVP]
    Feb 5, 2008
  5. Shahriar
    Replies:
    3
    Views:
    213
Loading...

Share This Page