Application structure

I am attempting to learn ruby and I can not seem to find how I would
structure a ruby application. Not a rails app just a simple ruby app. I
mostly have played around by putting several classes in one file and
running that.

Does one typically put rb files in a package structure like a java
application?
com.jenkins.util.MyClass?

Thanks for your help!

Does one typically put rb files in a package structure like a
java application?

I usually identify two kinds of “packaging” (or “grouping”):
internal and external.

Internal grouping is done with modules. Put all class that are
related in one module, optionally using submodules.

External grouping is the spreading of these modules and classes
over files and directories. Which directory structure you
choose is up to you. There’s no standard, not even a de facto
one.

Ruby doesn’t care about files and directories, but it does care
about modules. Thus, for Ruby, internal grouping is more
important than external packing. For you, as a human, the
opposite might be true…

gegroet,
Erik V. - http://www.erikveen.dds.nl/

Carl J. wrote:

I am attempting to learn ruby and I can not seem to find how I would
structure a ruby application. Not a rails app just a simple ruby app. I
mostly have played around by putting several classes in one file and
running that.

Does one typically put rb files in a package structure like a java
application?
com.jenkins.util.MyClass?

Thanks for your help!

http://i.loveruby.net/en/projects/setup/doc/devel.html

T.

The Ruby equivalent of java packages (i.e. namespaces)
is modules.

You can put many classes in the same file, that seems more
of a convenience than anything else. You basically separate
out classes into their own source files when the file becomes
too big.

Other than that you would package/modularize your app the
same way you organise these structures in other languages:

package classes that deal with the same problem domain
together (like UI, persistence, ‘service/utility’ etc.) and ensure
that the dependencies between packages are kept very clean.

Java has interfaces, (or ‘emasculated abstract base classes’ to
quote the pickaxe book), which are strongly used in structuring
applications across/within modular boundaries. Ruby doesn’t have these
but has something very interesting called mixins - blocks of
implementation that can be incorporated into your classes. I would
encourage you to use these - as they fulfill the java interface role
of enforcing API consistency, despite being totally different.

In any case Ruby LOC metrics and lean syntax mean you are not
as slavishly devoted to migrating code into other source files/modules
just
to retain legibility.

Ultimately, you structure apps in much the same way, guarding against
namespace collisions, mixins add a new dimension that you may or
may not need depending on your application scale.

Rails has totally different packaging best practices however (it
enforces
them).

On Aug 7, 2006, at 4:11 PM, Carl J. wrote:

Thanks for your help!
A project I’m working on looks like this:

$ find ar_mailer -type f | grep -v svn
ar_mailer/bin/ar_sendmail
ar_mailer/lib/action_mailer/ar_mailer.rb
ar_mailer/lib/action_mailer/ar_sendmail.rb
ar_mailer/LICENSE
ar_mailer/Manifest.txt
ar_mailer/Rakefile
ar_mailer/README
ar_mailer/test/action_mailer.rb
ar_mailer/test/test_armailer.rb
ar_mailer/test/test_arsendmail.rb


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On 08.08.2006 17:26, Richard C. wrote:

[snip]

Agreed.

Java has interfaces, (or ‘emasculated abstract base classes’ to
quote the pickaxe book), which are strongly used in structuring
applications across/within modular boundaries. Ruby doesn’t have these
but has something very interesting called mixins - blocks of
implementation that can be incorporated into your classes. I would
encourage you to use these - as they fulfill the java interface role
of enforcing API consistency, despite being totally different.

That’s something modules don’t do. There is no corresponding concept to
Java’s interface in Ruby. Ruby is not statically typed so there is no
point in having interfaces. Mixins are more like abstract classes that
you can inherit from (even from several of them, something that doesn’t
exist in Java).

[snip]

Agreed.

Kind regards

robert

On 8/7/06, Carl J. [email protected] wrote:

I am attempting to learn ruby and I can not seem to find how I would
structure a ruby application. Not a rails app just a simple ruby app. I
mostly have played around by putting several classes in one file and
running that.

Does one typically put rb files in a package structure like a java
application?
com.jenkins.util.MyClass?

Thanks for your help!

I think the way it often goes, in the simple case, is: you put one
top-level class (or module) per file, and name the file the same name
as the class (or module), but lowercase. Then you dump these files
into your app’s lib directory. Remember, from your ruby code, you
“require ‘filename’” (without the .rb filename extension) – you don’t
require the class (or module) name.

If you start creating subdirectories in your lib dir, I don’t think
the classes therein need to have any relationship to the other
classes. You would simply note the extra directory in your require
statements in your code: “require ‘vecmath/matrix’”, require
‘crystal/tetrahedron’", or whatever. The subdirectories are only there
to help you keep organized, and aren’t required.

When you have classes along with subclasses, I’m guessing these
usually just get lumped together into the same lib directory (or
subdirectory under lib). Though, again, they might be separated if you
want to keep them organized in some way, or if they just won’t stop
touching eachother and arguing while you’re trying to drive the car.

When you’ve got classes inside other classes (like Java’s inner
classes), I’m not sure what to do. Maybe as an example, see your Ruby
installation in …/lib/ruby/1.8/, and note cgi.rb, cgi/session.rb,
cgi/session/pstore.rb. I guess that’s the customary way to handle
those… (?)

—John

John G. wrote:

If you start creating subdirectories in your lib dir, I don’t think
the classes therein need to have any relationship to the other
classes. You would simply note the extra directory in your require
statements in your code: “require ‘vecmath/matrix’”, require
‘crystal/tetrahedron’", or whatever. The subdirectories are only there
to help you keep organized, and aren’t required.

Not so. You should be thoughtful about what you put in the toplevel.
It’s very easy to wipe out someone elses file this way. In general you
should ALWAYS put your files in a subdir named after your project. And
if need be, have one .rb file with the same name that the lib’s user
can require.

Other than that there is no standard. Organize your files and their
contents as you like.

T.

On 8/8/06, Trans [email protected] wrote:

Not so. You should be thoughtful about what you put in the toplevel.
It’s very easy to wipe out someone elses file this way. In general you
should ALWAYS put your files in a subdir named after your project. And
if need be, have one .rb file with the same name that the lib’s user
can require.

Sorry for being unclear: Everything I wrote in my post refers to your
own app’s lib directory.

For example, if I do all my work in /home/john/dev/ruby, and my
project is called “gemstones”, then my project directory will be
/home/john/dev/ruby/gemstones, and might contain stuff such as:

gemstones/
bin/
conf/
data/
docs/
lib/
gemstones.rb
vecmath/
point.rb
vector.rb
matrix.rb
crystal/
tetrahedron.rb
test/

—John

On 8/8/06, Trans [email protected] wrote:

gemstones/
crystal/
docs/

The reason is b/c someone else might have a project called ‘crystal’ or
‘vecmath’.

Ah! Right. That layout makes much more sense. Thanks!

—John

Thank you all very much for the replies!
You have no idea how very helpful this was…

John G. wrote:

data/
    ...

I’m not sure you were unclear. The thing is, it should be like this:

gemstones/
bin/
conf/
data/
docs/
lib/
gemstones.rb
gemstones/
vecmath/
point.rb
vector.rb
matrix.rb
crystal/
tetrahedron.rb
test/

The reason is b/c someone else might have a project called ‘crystal’ or
‘vecmath’.

T.