On 9/30/05, Austin Ziegler <halostatue / gmail.com> wrote:

> If that's how you read me, then you're not able to read me at all.

Well, you some off poorly when you lay into a persons motives,
perceptions and popularity, etc. I'm all ears for someone to tell me
how my ideas are flawed, but I want concreteness --not high
platitudes.

> I'm
> seeing you suggest something that has *great* potential for confusion
> without benefit that isn't *better* solved in other ways. The confusion
> factor is even greater since you modified your "namespace" idea to work
> with "/" instead of just ":".

I don't know. I think you might just be seeing the surface and not the
greater potential here. Granted this is not super big deal stuff
--especially for most projects. But it is nonethless a nice
convenience. Moreover, it can help make Ruby's lib system more robust.
In fact, if you think about it Gems starts to do this already, b/c it
keeps the packages in separate dirs and redirects to them as needed --
so I haven't invented anything new here except to let the end user
affect that redirection internal to his/her lib layout too.

> (By the by, a YAML file would be better for your purposes, and you can
> modify setup.rb to install non-.rb files; see the CVS for PDF::Writer to
> see how I installed .afm files, thanks to help from Aredridel.)

Thanks! I will have a look.

> If namespaces are accessible through ns/path/to/resource, then how am I
> to tell the difference between foo/bar/baz where foo is actually a
> directory in $LOAD_PATH as opposed to foo that might be a namespace?
> With ns:path/to/resource, the situation is mildly better, but I *still*
> believe that the problem is better solved elseplace. (I also think that
> some form of clear templating namespace is better, e.g.,
> <ns>/path/to/resource. If one even bothers with something like this.)

Perhaps, but keep in mind someone can just as easily clober a lib dir
on installations too b/c the conflicting names. At leat this allows
one to use a longer name --less likely to be clobbered and offer a
short alias. In fact it is funny you bring this up, b/c I have just
finished improving this part. Now one uses a couple methods intead of
using $LOAD_SPACE, one uses #register_library and #alias_library. That
way if someone has already registered a lib or alias of the same name
it will warn you.

> I personally think that you're entirely *too* ready to change the Ruby
> core when you get an idea in your head about how something should be
> solved, even if there's a much *better* solution that doesn't involve
> changing the core.

I'm not suggesting core change. I'm just suggesting an idea --what I'm
really interested in is better was to do what I'm trying to do.

> > And how he doesn't care about there's problems.
>
> I care that there's problems. I just don't see what you're talking about
> as a problem sufficient to make a pretty drastic -- and IMO ugly --
> change to Ruby's core. Not to suggest that he agrees with me, but I find
> myself very *conservative* toward Ruby's core like David Black.

Actually, I am too. I think people get me wrong b/c I throw things out
there --not to push a specific idea, but to explore it for better ways
of doing things. If that ultimately effects Ruby, great. But that's
not the goal.

> > It's pretty sad. The real world is about HUMAN engineering problems.
> > In reality there is no such thing as a computer engineering problem
>
> Okay, let me be a bit more explicit. You're trying to make a LARGE
> language change for a TINY language problem that is *mostly* (if not
> exclusively) isolated to the collection libraries that you've created.

Okay. I understand that. You're right, I'm dealing with my problem
right now --so it is very specific in that sense. But the problem
takes on proportions beyond me when I try to find a general solution.
Sure maybe it's not something people have been clamering to have, but
it also hasn't been availabe to them before. No one was clamering to
use Ruby before it existed either --why not just use Perl?

> I've been using Ruby since 2002 and haven't seen a need for anything
> like this. For the problem mentioned in ruby-talk:21296, there seems to
> have probably been a bug related to search path order -- and no mention
> of namespace is made at all. I found one such posting, but even the
> person there seemed to think that it was a "neat" idea, not sufficient
> for inclusion in the core. Sorry, but I just spent the last fifteen
> minutes looking for it and can't find it.

I can see why there's some confusion. The post is about the other half
of what this allows, ie. to move files around in a lib directory with
out having to change requires --essentially a differnt way to do
require local.

> > --people who believe otherwise generally expect others to do all sorts
> > of arcane things and can't understand why they don't --you know, like
> > write a Rake task to rearrange your lib before distribtion while
> > substituting every require line accordingly and placing in stub files
> > for all files renamed or deleted to give warning while documenting
> > each file with endless ugly {{{ }}}'s for there clever little dev
> > tools....
>
> ...and you're saying it's better to modify the core of Ruby because you
> either cannot or will not arrange your libraries in a more user-friendly
> way or use software engineering tools to take care of it for you
> dynamically? Sorry, but I think one of us is making an unreasonable
> request -- and it isn't me.

Like I said, I wasn't suggesting modifying the core. Just opening up
an idea. I posted it here b/c how it interelated w/ Rubygems, which
was of topic at the moement.

And I am trying to arrange the libs in a user-friendly way, but also
in a developer friendly way at the same time. And also as not to
interfere with other libs. I could just dump them all straight in to
site_ruby. How would you like 50 new files there and 25 new folders?

T.


P.S. If anyone is at all interested here's the coded I have thus far:

# Please provide ascend!
#require 'facets/method/pathname/ascend'
require 'pathname'

module LibRegistry

  $LOAD_SPACE = {}
  $LOAD_STACK = []

  $reqopt = {}
  $REQUIRE_STACK = []

  class << self
    def registry ; @registry ||= {} ; end
    def [](k) registry[k] ; end
    def []=(k,v) ; registry[k] = v ; end
    def keys ; registry.keys ; end
    def empty? ; registry.empty? ; end
    def method_missing( sym, *args, &blk )
      @registry.__send__( sym, *args, &blk )
    end
  end

  # recommend taguri, though not enforced
  def register_library( taguri, *directories )
    if LibRegistry[taguri]
      warn "Overriding previsouly defined library space -- #{taguri}."
    end
    LibRegistry[taguri] = directories
  end

  def alias_library( briefname, taguri, *subdirectories )
    raise "Unregistered library -- #{taguri}." unless LibRegistry[taguri]
    warn "Overriding previsouly defined library alias -- #{briefname}."
    if subdirectories.empty?
      LibRegistry[briefname] = LibRegistry[taguri]
    else
      unless (subdirectories - LibRegistry[taguri]).empty?
        raise "Aliased directories do not belong to registers library
-- #{taguri}."
      end
      LibRegistry[briefname] = subdirectories
    end
  end

  def match( fpath )
    named_paths = []
    unless LibRegistry.empty?
      sk = LibRegistry.keys.sort.reverse
      if md = %r{^(#{sk.join('|')})\/}.match(fpath)
        fpath.replace( md.post_match )  # internal effect!
        named_paths = LibRegistry[md[1]]
      end
    end
    return named_paths
  end

  # This acends the given dir looking for _.rb,
  # if found it breaks and evals for the local space.
  # Note: this needs some refinement to prevent
  # going all the way to root dir (how?)
  def load_ns( dir )
    return $LOAD_SPACE[ dir ] if $LOAD_SPACE.key?( dir )
    pn = Pathname.new( dir )
    dirstack = []
    pn.ascend(true) { |d|
      nsfile = d + '_.rb'
      if absns = $LOAD_SPACE[d.to_s]
        until dirstack.empty?
          $LOAD_SPACE[ dirstack.pop ] = absns
        end
        break
      elsif nsfile.file?
        nsdir = nsfile.dirname
        ns = eval( File.read( nsfile ) )
        absns = ns.collect{|e| (nsfile.dirname + e).cleanpath.to_s}
        dirstack << d.to_s
        until dirstack.empty?
          $LOAD_SPACE[ dirstack.pop ] = absns
        end
        break
      else
        dirstack << d.to_s
      end
    }
    $LOAD_SPACE[ dir ]
  end
  module_function :load_ns

  # include current directory NOW
  load_ns( Dir.pwd )

  # A new #require sub-method that allows for
  # namespaces. Also added require options.
  def require( fpath, options={} )
    success = false

    dir = File.expand_path( File.dirname(caller[0]) )
    loc = File.join( dir, fpath )

    relative_paths = load_ns( loc ) || []
    named_paths = LibRegistry.match( fpath )
    paths = named_paths | relative_paths

    $REQUIRE_STACK << $reqopt
    $reqopt = options

    $LOAD_STACK << $LOAD_PATH.dup
    $LOAD_PATH.replace( paths | $LOAD_PATH )
    begin
      success = super( fpath )
    ensure
      $LOAD_PATH.replace( $LOAD_STACK.pop )
      $reqopt = $REQUIRE_STACK.pop
    end

    success
  end

#NOTES:
#     if fpath.index(':')  # explict namespace
#       fpath, space = fpath.split(':').reverse
#       #inspace(space) if space
#     end

end

class Object
  include LibRegistry
end