![]() |
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. |
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 |
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? |
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 |
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. |
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. |
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.