[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[ANN] require_all 1.0.0: A wonderfully simple way to load your code

Tony Arcieri

6/9/2009 9:21:00 AM

require_all

A wonderfully simple way to load your code.

http://github.com/tarcieri/require_all/t...

Tired of futzing around with require statements everywhere, littering your
code with require File.dirname(__FILE__) crap? What if you could just point
something at a big directory full of code and have everything just
automagically load regardless of the dependency structure?

Wouldn=92t that be nice? Well, now you can!
require 'require_all'

You can now require_all in a multitude of different ways:
require_all *args

One of the easiest ways to require_all is to give it a glob, which will
enumerate all the matching files and load them in the proper order. For
example, to load all the Ruby files under the =91lib=92 directory, just do:
require_all 'lib/**/*.rb'

If the dependencies between the matched files are unresolvable, it will
throw the first unresolvable NameError.

Don=92t want to give it a glob? Just give it a list of files:
require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }

Or if you want, just list the files directly as arguments:
require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'

It=92s just that easy! Code loading shouldn=92t be hard.
Methodology

I didn=92t invent the approach this gem uses. It was shamelessly stolen fro=
m
Merb. Once upon a time at MountainWest RubyConf we were discussing how
horrible ActiveSupport=92s dependencies.rb hijacking of const_missing and
someone described the approach Merb used to me. It was so simple and clean!
Here=92s how it works:

1. Enumerate the files in the glob
2. Try to load all of the files. If we encounter a NameError loading a
particular file, store that file in a =93try to load it later=94 list.
3. If all the files loaded, great, we=92re done! If not, go through the
=93try to load it later=94 list again rescuing NameErrors the same way.
4. If we walk the whole =93try to load it later=94 list and it doesn=92t=
shrink
at all, we=92ve encountered an unresolvable dependency. In this case,
require_all will rethrow the first NameError it encountered.

Questions? Comments? Concerns?

You can reach the author on github or freenode: =93tarcieri=94

Or by email: tony@medioh.com

Got issues with require_all to report? Post =91em here:

Github Tracker <http://github.com/tarcieri/require_all/...
License

MIT (see the LICENSE file for details)
--=20
Tony Arcieri
medioh.com

8 Answers

Trans

6/9/2009 1:06:00 PM

0



On Jun 9, 5:21=A0am, Tony Arcieri <t...@medioh.com> wrote:
> require_all
>
> A wonderfully simple way to load your code.
>
> http://github.com/tarcieri/require_all/t...
>
> Tired of futzing around with require statements everywhere, littering you=
r
> code with require File.dirname(__FILE__) crap? What if you could just poi=
nt
> something at a big directory full of code and have everything just
> automagically load regardless of the dependency structure?
>
> Wouldn=92t that be nice? Well, now you can!
> require 'require_all'
>
> You can now require_all in a multitude of different ways:
> require_all *args
>
> One of the easiest ways to require_all is to give it a glob, which will
> enumerate all the matching files and load them in the proper order. For
> example, to load all the Ruby files under the =91lib=92 directory, just d=
o:
> require_all 'lib/**/*.rb'
>
> If the dependencies between the matched files are unresolvable, it will
> throw the first unresolvable NameError.
>
> Don=92t want to give it a glob? Just give it a list of files:
> require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
>
> Or if you want, just list the files directly as arguments:
> require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
>
> It=92s just that easy! Code loading shouldn=92t be hard.
> Methodology
>
> I didn=92t invent the approach this gem uses. It was shamelessly stolen f=
rom
> Merb. Once upon a time at MountainWest RubyConf we were discussing how
> horrible ActiveSupport=92s dependencies.rb hijacking of const_missing and
> someone described the approach Merb used to me. It was so simple and clea=
n!
> Here=92s how it works:
>
> =A0 =A01. Enumerate the files in the glob
> =A0 =A02. Try to load all of the files. If we encounter a NameError loadi=
ng a
> =A0 =A0particular file, store that file in a =93try to load it later=94 l=
ist.
> =A0 =A03. If all the files loaded, great, we=92re done! If not, go throug=
h the
> =A0 =A0=93try to load it later=94 list again rescuing NameErrors the same=
way.
> =A0 =A04. If we walk the whole =93try to load it later=94 list and it doe=
sn=92t shrink
> =A0 =A0at all, we=92ve encountered an unresolvable dependency. In this ca=
se,
> =A0 =A0require_all will rethrow the first NameError it encountered.
>
> Questions? Comments? Concerns?
>
> You can reach the author on github or freenode: =93tarcieri=94
>
> Or by email: t...@medioh.com
>
> Got issues with require_all to report? Post =91em here:
>
> Github Tracker <http://github.com/tarcieri/require_all/...
> License

require 'facets/kernel/require_all'

The idea predates Merb. However, it's always good too see how
implementations may have improved over time.

Also, I have seen another definition of #require_all floating around
that simply loads every .rb file in a given directory. I wonder if
both conceptions of this function (glob loading and directory loading)
could be integrated into one. Eg.

require_all 'some/path'

would do the same as

require_all 'some/path/*.rb'

Cheers,
T.

Daniel Berger

6/9/2009 2:37:00 PM

0



> -----Original Message-----
> From: bascule@gmail.com [mailto:bascule@gmail.com] On Behalf Of Tony
> Arcieri
> Sent: Tuesday, June 09, 2009 3:21 AM
> To: ruby-talk ML
> Subject: [ANN] require_all 1.0.0: A wonderfully simple way to load your
> code
>
> require_all
>
> A wonderfully simple way to load your code.
>
> http://github.com/tarcieri/require_all/t...
>
> Tired of futzing around with require statements everywhere, littering
> your
> code with require File.dirname(__FILE__) crap? What if you could just
> point
> something at a big directory full of code and have everything just
> automagically load regardless of the dependency structure?
>
> Wouldn't that be nice? Well, now you can!
> require 'require_all'
>
> You can now require_all in a multitude of different ways:
> require_all *args
>
> One of the easiest ways to require_all is to give it a glob, which will
> enumerate all the matching files and load them in the proper order. For
> example, to load all the Ruby files under the 'lib' directory, just do:
> require_all 'lib/**/*.rb'
>
> If the dependencies between the matched files are unresolvable, it will
> throw the first unresolvable NameError.
>
> Don't want to give it a glob? Just give it a list of files:
> require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file(f) }
>
> Or if you want, just list the files directly as arguments:
> require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'
>
> It's just that easy! Code loading shouldn't be hard.
> Methodology
>
> I didn't invent the approach this gem uses. It was shamelessly stolen
> from
> Merb

Trust me, Merb was not the first library to come up with Java style/globbing
import statements. I remember this being discussed a *long* time ago, and it
generally crops up from time to time on the mailing list. I'm pretty sure it
was an RCR at one point (for altering the behavior of Ruby's own require),
but I can't find it now.

But, now that I'm looking on the RAA, I can't find a library for it. So,
still a nice thing to have, thanks. :)

Regards,

Dan


Tony Arcieri

6/9/2009 5:31:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jun 9, 2009 at 7:06 AM, trans <transfire@gmail.com> wrote:

>
> require 'facets/kernel/require_all'
>

Bah, should've checked facets first, but that really is the problem with
facets... it's a big kitchen sink and you never know what you're going to
find in there or not

That said, this was yanked out of a larger system and incorporates some
hacks for living along ActiveSupport and the boogiemen which lurk inside
dependencies.rb.

The idea predates Merb. However, it's always good too see how
> implementations may have improved over time.
>

Thanks! I figure if nothing else it could have a more powerful API.


> Also, I have seen another definition of #require_all floating around
> that simply loads every .rb file in a given directory. I wonder if
> both conceptions of this function (glob loading and directory loading)
> could be integrated into one. Eg.
>
> require_all 'some/path'
>
> would do the same as
>
> require_all 'some/path/*.rb'
>

That seems as simple as checking if the given path is a directory. Perhaps
it'd be a nice feature for 1.0.1

--
Tony Arcieri
medioh.com

Tony Arcieri

6/9/2009 7:00:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jun 9, 2009 at 7:06 AM, trans <transfire@gmail.com> wrote:

> Also, I have seen another definition of #require_all floating around
> that simply loads every .rb file in a given directory. I wonder if
> both conceptions of this function (glob loading and directory loading)
> could be integrated into one. Eg.
>
> require_all 'some/path'
>
> would do the same as
>
> require_all 'some/path/*.rb'
>

You ask for it, you get it!

I've just released require_all 1.0.1, which in addition to all the other
functionality accepts a directory name as an argument and will glob all the
*.rb files underneath it.

Figured I'd spare the list an additional release announcement :)

--
Tony Arcieri
medioh.com

Roger Pack

6/10/2009 5:53:00 PM

0

> Tired of futzing around with require statements everywhere, littering
> your
> code with require File.dirname(__FILE__) crap? What if you could just
> point
> something at a big directory full of code and have everything just
> automagically load regardless of the dependency structure?

Wow I really like this idea.
--
Posted via http://www.ruby-....

Joel VanderWerf

6/10/2009 6:11:00 PM

0

Roger Pack wrote:
>> Tired of futzing around with require statements everywhere, littering
>> your
>> code with require File.dirname(__FILE__) crap? What if you could just
>> point
>> something at a big directory full of code and have everything just
>> automagically load regardless of the dependency structure?
>
> Wow I really like this idea.

Hm, what about

module Foo
class HonkinBigResource
end

RESOURCE_LIST << HonkinBigResource.new
# defer until RESOURCE_LIST defined, if necessary

class Bar < Base
# Base may be undefined, so defer loading of this file
end
end

This could result in wasted time recreating a resource, duplicates on
the list, etc.

Sure, it's possible to program defensively to avoid the above, but I'd
rather set up a proper dependency structure with explicit requires.

Also, all uses of defined?(SomeClass) will have more or less random
results, won't they?

OTOH, maybe this is like static vs. dynamic typing, and I'm just too old
school to get it ;)

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Tony Arcieri

6/11/2009 6:32:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Wed, Jun 10, 2009 at 12:11 PM, Joel VanderWerf
<vjoel@path.berkeley.edu>wrote:

> Hm, what about
>
> module Foo
> class HonkinBigResource
> end
>
> RESOURCE_LIST << HonkinBigResource.new
> # defer until RESOURCE_LIST defined, if necessary
>
> class Bar < Base
> # Base may be undefined, so defer loading of this file
> end
> end
>
> This could result in wasted time recreating a resource, duplicates on the
> list, etc.
>

Yes, there are potential issues with this approach if you do that sort of
thing.

The larger issues are when you use this with something like ActiveSupport
loaded which redefines const_missing on everything. This will invoke that
const_missing callback whenever it hits a missing constant, and in
ActiveSupport its const_missing handler is an absolute nightmare.

Also, all uses of defined?(SomeClass) will have more or less random results,
> won't they?
>

If you have code in the toplevel or a class/method body which is using
"defined?" then it is possible you will get nondeterministic results
depending on the order code is loaded in (i.e. there may be multiple
possible orderings which satisfy all dependencies), provided those constants
are getting defined in another file which you're pulling in through
require_all.

However, if you have a file which defines a bunch of constants (e.g. a
config file) you can just load that file first, then use require_all to pull
in the rest of your code.

The behavior of "defined?" inside of methods will work exactly as it always
did since that code isn't actually executed until the method is invoked.

--
Tony Arcieri
medioh.com

Joel VanderWerf

6/11/2009 6:59:00 PM

0

Tony Arcieri wrote:
> The behavior of "defined?" inside of methods will work exactly as it always
> did since that code isn't actually executed until the method is invoked.

True, but sometimes methods get invoked at load time...

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407