From: David Brady Date: 2005-08-26T03:14:08+09:00 Subject: Re: Extending Code Cleanly Molitor, Stephen L wrote: >require 'foo' ># or: >require 'foo_without_extensions' > > I would also be happy with 2 ways to load foo: require 'foo' require 'foo/string' require 'foo/fixnum' require 'foo/date' being equivalent to require 'foo/extensions' or somesuch. The contents of 'foo/extensions' would literally be just the four earlier requires. Both ways (foo,foo_without_extensions vs. foo,foo/extensions), have pros and cons. I guess most people would want extensions rather than to disable them, and in general I like to see the shorter syntax do the most desirable thing; so maybe 'require "foo"' should bring in extensions, and foo_without_extensions should be the nonintrusive version. Then again, when your core classes Go Wrong, it's pretty horrible, so maybe pulling in extensions explicitly is better. The 'foo/extensions' thing looks the most "honest" to me--you're telling the reader that you are mucking in code space that they might not expect. I see only two issues with the syntax: - should 'foo/extensions' ALSO import 'foo'? I think it should. My C++ tainted mind wanted to say no at first, but I think this is not the Ruby way. require 'test/unit' brings in Test AND Test::Unit just fine, for example. - because you can put extensions anywhere, you cannot trust in the "reverse case", e.g. just because 'foo/extensions' exists, that require 'foo' *won't* go making extensions. I would be content to see this in an RCR: a warning level could exist that will tell you if a file named other than 'extensions.rb' reopens an existing class, and this warning should be disabled by default (let's not hamper the agility of short scripts). A safe_level could also exist that turns that warning into an error, perhaps unless $0 == __FILE__ (again to favor the short scripts). Finally, and this is left as an exercise to those readers who know a lot more Ruby than me, I think it is possible to write a ruby module that provides this functionality right now. Adding an extension to Kernel#extend and related functions to raise an exception if a Core or StdLib method is overriden in a file not named extensions.rb. Pity you can't freeze methods, or you could prevent people hacking out your change by freezing Kernel#extend (but still leaving Kernel open to extension). But now we're talking about deliberate, premeditated evil, and there's just no way to prevent that in the code--that's what baseball bats and poorly lit parking lots are for. :-) -dB -- David Brady ruby-talk@shinybit.com I'm having a really surreal day... OR AM I?