SOT (slightly offtopic): General OOP question

Hi,

I have a general question about OOP.

There is no problem for me to decide how arrange and design classes
_inside_ of a program but I get a "problem" regulary, when trying to
decide what to do with "things between" the program and the outside
world.

For example:
A Ruby script should read a file and do something with its contents.
What does the "clean white rule of OOP" say:
The "physics of the file" (open(),read(),close() and the according
error handling) become a class returning an object "containing"
the Filehandle? Or the contents of that file?

Other example:
I want to write a script which correspond with the user with the
classic UNIX-like opetions.

Shall i make a class for handling the options alone and returning an
object containing...what? The accordingly set configuration
variables? The options alone, so that the other classes can take the
informations they want?

Or is it more "OOP-like" when this class will handle "more"...

Or in other words: When it comes to data, which travel between the
inside world and the outside world of a script I am not sure to
decide how much of work the accompanied Class will do with them.

Is there any "official" rule of OOP, which I can guide me for better
deciding in such thing ?

Thank you very much in advance for any help ! :O)

Kind rgards,
Meino

Meino Christian Cramer wrote:

Hi,

I have a general question about OOP.

There is no problem for me to decide how arrange and design classes
_inside_ of a program but I get a "problem" regulary, when trying to
decide what to do with "things between" the program and the outside
world.

For example:
A Ruby script should read a file and do something with its contents.
What does the "clean white rule of OOP" say:
The "physics of the file" (open(),read(),close() and the according
error handling) become a class returning an object "containing" the Filehandle? Or the contents of that file?

It depends. It sounds like this is an implementation detail; as the user of a a file-based class, I may want to ask an object if the file contains the word 'foo'. Whether the object has to go open and scan the file on disk, or already has the contents in memory, the client probably shouldn't care. But it may depend on what role or purpose this file-based object is supposed to fill.

Other example:

<snip/>

It may be worth trying to write unit tests to see what design arises. OO is a very useful technique for code organization, but it does not always map well to every real-world scenario; there is often no One True Way to model something. You just have to try things out to see what feels like a good fit.

James

Hi,

I have a general question about OOP.

There is no problem for me to decide how arrange and design classes _inside_
of a program but I get a "problem" regulary, when trying to decide what to
do with "things between" the program and the outside world.

For example: A Ruby script should read a file and do something with its
contents. What does the "clean white rule of OOP" say: The "physics of the
file" (open(),read(),close() and the according error handling) become a
class returning an object "containing" the Filehandle? Or the contents of
that file?

i would agree with that. the only time you have problems are if the files are
huge. in that case you may have to provide iterators. i have a class that
does exactly that for dmsp satelite data. the data is organized like:

start header
key=value
k2=v2
end header
....
binary records
....
binary records
...

so i parse the header and then mmap in the rest of the file (massive kernel
bug with this for rhe. note to all interested parties) and provide accessors
for header values and scanlines

   satelite = ols.header[ %r/sat/o ]
   scanline = ols[ 42000 ]

and i've also provided iterators like

   ols.each_scanline do |scanline|
     scanline[0..42] = 255
   end

which map back changes made to the scanline

i'm quite happy with the abstraction and have been able to do a lot of useful
work quickyly with the design... i've got similar classes for envi header
files and other data formats.

Other example: I want to write a script which correspond with the user with
the classic UNIX-like opetions.

Shall i make a class for handling the options alone and returning an object
containing...what? The accordingly set configuration variables? The options
alone, so that the other classes can take the informations they want?

i've struggled with this one alot. but lately i've been making 'Main' classes
which parse their options into a hash removing the leading '--' chars. for a
while i was a fan of using symbols as hash keys, but now use only strings.
this is mostly due to the wonderful ease of using yaml files as
configuration files. when developing i make even unrecognized options load
cleanly into the options hash without warning. then i pass this hash to
relevent methods, for instance

   class Main
     def run
       @opts = parse_opts
       @config = parse_config
       @options = @config.update @opts

       @worker = Worker.new arg, @options
     end
   end

   class Worker
     def intialize arg, opts = {}
       @arg = arg
       @opts = opts
     end
     def do_work
       if @opts['some_option']
         ...
       elseif @opts['some_new_option_just_passed_from_command_line']
         ...
       end
     end
   end

which allows me to quickly get info from the command line or a yaml config
file deeply into my code without having to explictly pass it or make some sort
of globally accessible config. now that i think about it this is probably
terrbile OO design according to meyer or someone like that... but for the
people up the hall asking 'can you add XXX in 5 minutes' it's probably 'good'
OO design. :wink:

Or is it more "OOP-like" when this class will handle "more"...

Or in other words: When it comes to data, which travel between the inside
world and the outside world of a script I am not sure to decide how much of
work the accompanied Class will do with them.

Is there any "official" rule of OOP, which I can guide me for better
deciding in such thing ?

i choose the path that solves the problem quickly and that can adapt to
variations quickly - over extreme robustness - but i'm probably in the
minority.

Thank you very much in advance for any help ! :O)

Kind rgards,
Meino

very cool questions.

-a

···

On Wed, 30 Jun 2004, Meino Christian Cramer wrote:
--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Hi,

I have a general question about OOP.

There is no problem for me to decide how arrange and design classes
_inside_ of a program but I get a "problem" regulary, when trying to
decide what to do with "things between" the program and the outside
world.

For example:
A Ruby script should read a file and do something with its contents.
What does the "clean white rule of OOP" say:
The "physics of the file" (open(),read(),close() and the according
error handling) become a class returning an object "containing"
the Filehandle? Or the contents of that file?

OOP doesn't say anything about what the contents should be, only that objects
should encapsulate the contents safely. You are free to arrange any design
pattern you want. Doing either is perfectly acceptable.

Other example:
I want to write a script which correspond with the user with the
classic UNIX-like opetions.

Shall i make a class for handling the options alone and returning an
object containing...what? The accordingly set configuration
variables? The options alone, so that the other classes can take the
informations they want?

Or is it more "OOP-like" when this class will handle "more"...

Or in other words: When it comes to data, which travel between the
inside world and the outside world of a script I am not sure to
decide how much of work the accompanied Class will do with them.

I usually hold command-line options, application-specific environment
variables and configration file settings grouped together as constants in a
container module (so they're available globally like MyModule::OPTION) and I
read all three sources, setting the constants as I go.

Is there any "official" rule of OOP, which I can guide me for better
deciding in such thing ?

There are lots of things written on the principals of OOP (Google turns up
many hits on the subject), but once you know the basics, experience is the
best teacher.

  Sean O'Dell

···

On Wednesday 30 June 2004 07:15, Meino Christian Cramer wrote:

While others have answered this competent I'd like to add some remarks:

"Meino Christian Cramer" <Meino.Cramer@gmx.de> schrieb im Newsbeitrag
news:20040630.161538.39157221.Meino.Cramer@gmx.de...

Hi,

I have a general question about OOP.

There is no problem for me to decide how arrange and design classes
_inside_ of a program but I get a "problem" regulary, when trying to
decide what to do with "things between" the program and the outside
world.

For example:
A Ruby script should read a file and do something with its contents.
What does the "clean white rule of OOP" say:
The "physics of the file" (open(),read(),close() and the according
error handling) become a class returning an object "containing"
the Filehandle? Or the contents of that file?

That depends on the usage. If you do something stream oriented, you will
likely be working with an IO instance - that is already an abstraction of
a stream. On other occations, where you just need the contents of a file
you might just write a function that returns the whole contents in a
string or in some other kind of object.

Other example:
I want to write a script which correspond with the user with the
classic UNIX-like opetions.

Shall i make a class for handling the options alone and returning an
object containing...what? The accordingly set configuration
variables? The options alone, so that the other classes can take the
informations they want?

Or is it more "OOP-like" when this class will handle "more"...

If you have a huge complex application, having a single class with all the
settings has the drawback, that all modules / components of your
application physically depend on this class and this class in turn depends
conceptually on all components. Although this is not a circular
dependency in the strictest meaning of the term, I regard it problematic,
because the single settings class will quite likely grow very large and
thus the likelyhood of name collisions increases; plus you can't separate
all modules easily from each other.

Having one config class per component is IMHO a superior approach. Of
course you then need a single place in the program that fetches config
info from the outside world (command line, rc file, a database - whatever)
and initializes individual settings classes.

But, of course that depends on your application's size. You might have
only a single instance of some class at the top script level that does all
the work and thus will carry config info as well. In that case
introducing an extra class for this would be overhead.

As always, these kind of questions can't be answered on a general basis.
It depends... :slight_smile:

Kind regards

    robert

Ara.T.Howard wrote:

... for a while i was a fan of using symbols as hash keys,
but now use only strings. this is mostly due to the wonderful
ease of using yaml files as configuration files ...

Sorry, I just noticed this and it almost spoilt
my enjoyment of an iced biscuit.

Have you noticed that '_why'.capitalize has improved Symbol#to_yaml ?

require 'yaml'
puts :asym.to_yaml

#-> ruby 1.9.0 (2004-06-25)
#-> --- :asym

## - was ...

#-> ruby 1.8.0 (2003-08-30)
#-> --- !ruby/sym asym

If there's another reason for preferring strings, I hope I
won't be trying to drink a glass of milk when I read it.

:wink:

daz

i had NOT noticed that. thanks for the heads up!

-a

···

On Sat, 3 Jul 2004, daz wrote:

Ara.T.Howard wrote:

... for a while i was a fan of using symbols as hash keys,
but now use only strings. this is mostly due to the wonderful
ease of using yaml files as configuration files ...

Sorry, I just noticed this and it almost spoilt
my enjoyment of an iced biscuit.

Have you noticed that '_why'.capitalize has improved Symbol#to_yaml ?

require 'yaml'
puts :asym.to_yaml

#-> ruby 1.9.0 (2004-06-25)
#-> --- :asym

## - was ...

#-> ruby 1.8.0 (2003-08-30)
#-> --- !ruby/sym asym

If there's another reason for preferring strings, I hope I
won't be trying to drink a glass of milk when I read it.

:wink:

daz

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================