Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Ruby (http://www.velocityreviews.com/forums/f66-ruby.html)
-   -   File-based Code Encapsulation (http://www.velocityreviews.com/forums/t836906-file-based-code-encapsulation.html)

Trans 01-03-2007 10:36 PM

File-based Code Encapsulation
 
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.



ara.t.howard@noaa.gov 01-03-2007 10:52 PM

Re: File-based Code Encapsulation
 
On Thu, 4 Jan 2007, Trans wrote:

> 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.


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
--
if you find yourself slandering anybody, first imagine that your mouth is
filled with excrement. it will break you of the habit quickly enough. - the
dalai lama


spooq 01-04-2007 10:40 AM

Re: File-based Code Encapsulation
 
On 1/3/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> 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?


ara.t.howard@noaa.gov 01-04-2007 02:57 PM

Re: File-based Code Encapsulation
 
On Thu, 4 Jan 2007, spooq wrote:

> On 1/3/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> 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
--
in the practice of tolerance, one's enemy is the best teacher.
- the dalai lama


Trans 01-05-2007 03:31 AM

Loading, Python vs. Ruby [was: File-based Code Encapsulation]
 
gabriele renzi wrote me with an interesting observation:

> If you just add
>
> and a directory is a module, too so that
> require 'foo'
> loads module Foo
> and
> require 'foo/bar'
> requires module Foo::Bar
>
> and you have the python's import system, which is a very good thing imo
> and could reduce ruby's stdlib size of a 1/2% :)


then i found this post from Guido van Rossum in 2003

http://mail.python.org/pipermail/pyt...er/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.



Trans 01-05-2007 03:49 AM

Re: File-based Code Encapsulation
 

ara.t.howard@noaa.gov wrote:
> On Thu, 4 Jan 2007, Trans wrote:
>
> > 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.

>
> 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.

> 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:
>
> [snip examples]
>
> 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.


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.



Michael P. Soulier 01-05-2007 04:03 AM

Re: Loading, Python vs. Ruby [was: File-based Code Encapsulation]
 
On 1/4/07, Trans <transfire@gmail.com> wrote:
> then i found this post from Guido van Rossum in 2003
>
> http://mail.python.org/pipermail/pyt...er/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
--
Michael P. Soulier <msoulier@digitaltorque.ca>
"Any intelligent fool can make things bigger and more complex... It takes a
touch of genius - and a lot of courage to move in the opposite direction."
--Albert Einstein



All times are GMT. The time now is 02:13 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57