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