From: "Christoffer Lernö" Date: 2008-07-02T21:38:02+09:00 Subject: Re: Something like import/package in java? On 1 Jul 2008, at 15:02, Charles Oliver Nutter wrote: > Christoffer Lernö wrote: >> Readability, clear division of responsibilities, ease of development. >> - Even with unit test suites I don't feel secure that the test >> isn't conditional on files included by other tests. >> - If I want to include all classes from a dir, I have to manually >> scan through the dir. >> - Clear cut organization of files. >> - Crystal clear dependencies between files. >> - Lots of other small worries I can't quite put my finger on. >> There's some breaking point around 20+ files for me (excluding unit >> tests), when it becomes really important to have a well-defined >> organization of my classes, and here just heaping classes into >> different files doesn't quite cut it for me. > > To namespace your methods modules and classes, you want to embed > them within other modules. The typical convention is that your x/y/z > dir hierarchy will be mirrored in the z.rb file with a nested module > X; module Y; class Z structure. > > Coming from Java, the first thing to remember is that Ruby does not > impose (or gift, depending on your perspective) a mandatory file > path == package structure, so you're free (or required) to do > namespacing however you see fit. If you want a 50-deep dir hierarchy > of .rb files to all dump stuff into the global namespace, you can do > so. But you would typically apply your own namespacing for exactly > the reasons you describe above. For me it is not so much a namespace-issue. It is rather dependency and include issue. The most frequent use of java imports for me is actually as an indicator of dependencies as I only in very special circumstances would use the fully qualified name of a class. This means that I can read from the imports the actual dependencies on external classes. This helps a lot during refactoring and testing. Perhaps you feel I don't understand your point, and that may be so. I don't quite see how using namespaces would solve these issues. I suppose part of my include worries could be solved with something like this: 8<---------------- def package path relative_path, file_name = File.split($PROGRAM_NAME) top_path = File.expand_path(relative_path) package_path = path.split(/\./) current_path = top_path built_path = "" package_path.reverse.each do |path_part| current_path, dir = File.split(current_path) built_path += "#{File::SEPARATOR}#{dir}" raise "Package not in correct directory structure, expected #{package_path.join(File::SEPARATOR)} was #{built_path}" if path_part ! = dir end $package_top_dir = current_path end def import path $package_top_dir ||= current_path import_path_parts = path.split(/\./) file = import_path_parts.pop import_dir = Dir.new($package_top_dir + File::SEPARATOR + (file.empty? ? "" : import_path_parts.join(File::SEPARATOR))) if (file == "*") import_dir.entries.each do |file| require(import_dir.path + File::SEPARATOR + file) if file =~ / \.rb$/ end else require import_dir.path + File::SEPARATOR + file + ".rb" end end 8<-------------- If you have this code then the line package "some_dir.next_dir" import "some_other_dir.foo" in file lib/some_dir/next_dir/bar.rb will require the file lib/some_other_dir/foo.rb regardless from what directory you run the file (excluding playing around with .. and .) (It would be neater to be able to automatically add the contents of bar.rb to be part of a module named SomeDirNext::NextDir, by default) /C