# File-based Code Encapsulation

**URL:** <https://www.ruby-forum.com/t/file-based-code-encapsulation/81104>\
**Category:** Ruby\
**Created:** [January 3, 2007, 11:36pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104 "2007-01-03T23:36:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 3, 2007, 11:36pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/1 "2007-01-03T23:36:52Z")

</div>

Hi–

I’m having a little debate with myself. On my current project I have a  
bunch of little reusable task scripts that a command line tool runs.  
The scripts are written as the top-level (although I actually simulate  
the top-level when running them). So for example a script would just be  
something like:

# example.rb

def example  
puts “This is an example!”  
end

Then on the command line I would do:

% mytool example  
This is an example!

That’s all well and good, but many of the scripts have generally useful  
routines and I would like them to be accessible by other programs too,  
not just my command line tool. So I thoght maybe it would be better if  
a module were required to wrap the defs.

# another.rb

module MyToolAnother

```
def another
  puts "This is another!"
end

```

end

That works, of course, but it adds an additonal layer of essentially  
redundant code, which IMHO is ugly.

Then I got to thinking. Why don’t we write resuable lib in this fashion  
anyway and just create our own containers on the fly when loading them?

MyToolExample = load\_as\_module “example.rb”

What intersting about that is then we could determine in what capacity  
it is to be used. For example:

# adds module\_function

MyToolExample = load\_as\_function\_module “example.rb”

# adds self extend

MyToolExample = load\_as\_self\_extended\_module “example.rb”

Or even

MyToolExample = load\_as\_class “example.rb”

We could even have include and extend take a lib path.

include “example.rb”

Of course this effectively puts encapsulation, at least at the top  
level, on a per-file basis. But in many respects that seems kind of  
nice. It increases flexability and reduces configuration complexity.

So what do your think? Is this technique worth promoting? Or am I being  
silly and should just wrap all my scripts in modules?

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 4, 2007, 11:42am UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/2 "2007-01-04T11:42:21Z")

</div>

On 1/3/07, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> now i have a single command line program which loads this lib then takes the  
> first command line argument as a method to send to the module. remaining  
> command-line parms are parsed in a sensible way allowing ints, strings,  
> floats, bools, lists, hashes, and combinations of those. whatever value is  
> returned by the function is dumped on stdout.

Would it be possible for you to post this code?

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 3, 2007, 11:54pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/3 "2007-01-03T23:54:56Z")

</div>

On Thu, 4 Jan 2007, Trans wrote:

> def example  
> not just my command line tool. So I thoght maybe it would be better if  
> end  
> it is to be used. For example:
> 
> T.

wrap up the functionality into a lib, require that from your scripts,  
and make  
accessing instance methods from the command-line easy. i’ve used this  
pattern  
many times. here is an example from our NRT (near-real-time) system  
which  
allows me to call any module function from the command line:

mussel: ~ \> cat nrtlib.rb  
module NRT  
def self.foobar(\*a) p a end

```
 # many, many, many lines of code

```

end

now i have a single command line program which loads this lib then takes  
the  
first command line argument as a method to send to the module.  
remaining  
command-line parms are parsed in a sensible way allowing ints, strings,  
floats, bools, lists, hashes, and combinations of those. whatever value  
is  
returned by the function is dumped on stdout. examples.

mussel:~ \> nrt foobar  
— []

## mussel:~ \> nrt foobar 42

- 42

## mussel:~ \> nrt foobar 1,2,3

- 
  - 1
  - 2
  - 3

## mussel:~ \> nrt foobar 1,2,3 k:v

- 
  - 1
  - 2
  - 3

- k: v

## mussel:~ \> nrt foobar 1,2,3 k:v a:b

- 
  - 1
  - 2
  - 3

- k: v  
a: b

## mussel:~ \> nrt foobar 42.0 string

- 42.0
- string

## mussel:~ \> nrt foobar 42.0 string key:val

- 42.0
- string
- key: val

now, yaml input is also allows by giving ‘–’ as a commnad line arg

## mussel:~ \> nrt foobar 42.0 string key:val | nrt foobar –

- 42.0
- string
- key: val

and the arg ‘-’ indicates a simple unix style list, one element per  
line, on  
stdin:

## mussel:~ \> printf “a \n b \n c \n” | nrt foobar -

- a
- b
- c

the result is that any library/module routine is instantly availible  
from the  
command line - makes testing a breeze!

obviously not all routines are easy to use this way but, by sticking to  
simple  
interfaces/function call signatures many of them can be.

it’s a useful pattern.

food for thought.

-a

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 6, 2007, 7:19pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/4 "2007-01-06T19:19:00Z")

</div>

On Thu, 4 Jan 2007, spooq wrote:

> On 1/3/07, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > now i have a single command line program which loads this lib then takes  
> > the  
> > first command line argument as a method to send to the module. remaining  
> > command-line parms are parsed in a sensible way allowing ints, strings,  
> > floats, bools, lists, hashes, and combinations of those. whatever value is  
> > returned by the function is dumped on stdout.
> 
> Would it be possible for you to post this code?

sure. i’ve been trying to organize it into a library, but it’s hard to  
abstract. i’ll see if i can gin up something later today.

regards.

-a

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 6, 2007, 7:30pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/5 "2007-01-06T19:30:57Z")

</div>

gabriele renzi wrote me with an interesting observation:

> and could reduce ruby’s stdlib size of a 1/2% 🙂  
> then i found this post from Guido van Rossum in 2003

[[Python-Dev] Relative import](http://mail.python.org/pipermail/python-dev/2003-December/041065.html)

(did it ever happen?)

this really gets me wondering, how do Ruby’s and Python’s loading  
mechanisms match-up? which do you think is better?

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 19, 2007, 4:29pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/6 "2007-01-19T16:29:52Z")

</div>

On 1/4/07, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> then i found this post from Guido van Rossum in 2003
> 
> [[Python-Dev] Relative import](http://mail.python.org/pipermail/python-dev/2003-December/041065.html)
> 
> (did it ever happen?)

Yes.

> this really gets me wondering, how do Ruby’s and Python’s loading  
> mechanisms match-up? which do you think is better?

I prefer Python’s, honestly. I also like that in Perl, the convention  
at least is that what you use is what the namespace is. So, if I use

use File::Copy;

Then the functions are in File::Copy::\* by convention.

Mind you, you’d typically use it like

use File::Copy qw(move copy);

And just call move() or copy() directly.

In Ruby I guess that would be

use File::Copy  
include File::Copy

to achieve the same?

Coming from Perl and Python, I did find Ruby’s system confusing. The  
poor documentation makes it even more so.

Mike

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [January 6, 2007, 7:30pm UTC](https://www.ruby-forum.com/t/file-based-code-encapsulation/81104/7 "2007-01-06T19:30:49Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > # example.rb
> > 
> > That’s all well and good, but many of the scripts have generally useful  
> > end
> > 
> > So what do your think? Is this technique worth promoting? Or am I being  
> > silly and should just wrap all my scripts in modules?
> > 
> > T.
> 
> wrap up the functionality into a lib, require that from your scripts, and make  
> accessing instance methods from the command-line easy.

in this particluar case it’s not suitable to separate the functionality  
into separate lib b/c it’s important that these scripts be  
self-contained.

> interfaces/function call signatures many of them can be.
> 
> it’s a useful pattern.
> 
> food for thought.

very cool. yea, i wondn’t mind adding a tool like that to my current  
project. i wonder how extensive a tool like that could be. would it be  
possible to run arbitrary methods --even if they were in classes or  
non-function modules?

T.
