Class vrs. method


#1

I’ve been thinking about this question for days, and have yet to come up
with a satisfactory answer. I have deep respect for the “smarts”
available on this list, so I’ll toos the question out here. I’ve been
programming in Ruby for possibly a couple of years, learning what I need
to know to get something done, at the time I need to know it. I don’t
have much time for pure Ruby-study, although I much wish I did. I’m
presently writing database program in ruby, using only ruby (no database
engine), which will manage a network of nodes (labels) and relationships
(also labels). It’s simple, but potentially very powerful, and a great
opportunity for me to push into new territory with Ruby. It’s coming
along well, and I’m much enjoying the experience.

I’m getting it done by writing a number of methods. I keep looking at
other people’s programming, and I see many, many classes. Some of these
classes look pointless to me. A mere method would have done the trick.
Why a “class”? I personally feel no need whatsoever to actually USE one.
I’m getting everything done easily and artfully with mere methods. I
simply don’t get it - about classes. It looks like an elegant idea, and
in more complex programming I can imagine why one might use them,
but…I’ve simply cannot find a reason to bother.

I’ve read a lot about them, but…here’s my question:

Am I missing something? Can anyone give me a compelling reason to write
fewer methods and more classes?

If anyone’s interested, the program to which I referred may be examined
at

http://tomcloyd.com/misc/setnet.txt

(I had to change the file extension to txt, as ‘rb’ refused to load in
my browser, and might well do that in yours as well.)

As I’ve puzzled about this for days, I’m very interested to see what
better informed people have to say about this question. Please
understand that I do grasp the basics, but do NOT see what the
compelling reason is to use a class in a reasonably simple program.
Thanks!

Tom


#2

On Sun, Dec 7, 2008 at 4:58 AM, Tom C. removed_email_address@domain.invalid wrote:

Am I missing something? Can anyone give me a compelling reason to write
fewer methods and more classes?

If anyone’s interested, the program to which I referred may be examined at

http://tomcloyd.com/misc/setnet.txt

Tom,

Looks like you’re very capable and comfortable with procedural
programming. Object oriented programming is a different style.

Why would you want to switch to OO style? Ultimately because OO is a
fundamental design decision in Ruby and your code will just flow more
easily if you follow that paradigm. In my mind the fact that an object
system has been tacked onto or designed into every major programming
language in general use today indicates that OO is either a) being
forced on us by language designers eager to look “modern” or b)
actually pretty useful. I’ll go with (b).

Specifically in your case:

In your program how can I set up two different sets of nodes,
relationships, and links at the same time? You’re building excellent
accessor methods to global variables (even though you are using
@instance_variable notation instead of $global_variable notation, you
only have one namespace in use so they are really just globals). But I
can only ever have one set at a time. With object orientation,
whatever your program does, you could do multiple times by
instantiating the class as many different times as needed. What if,
once you finish your main SetNet program, you find you want to write
another program to build one SetNet based on an existing SetNet?

Also, your add_node and add_relation are the exact same code except
for the global hash variable they use. While you could build a more
generalized add_something function and pass the hash as a parameter,
it would be more readable (and flexible) in the long run to build out
your base functionality in a Class and then use multiple instances of
it, or even subclasses if needed, to fine-tune the exact
functionality.

You also do a lot of message passing. Like manage_log, accepts a
string that the string uses in a case statement to decide what to
really do. With objects, that string is not needed. You could just
have @my_log.open and @my_log.close. You could also then set a log
filename in your @my_log = MyLog.new(“logfile.txt”) statement. That
way you can have multiple log files, or you can decide the name of the
logfile at the level of the calling code, rather than in your logging
code. You can still set a default filename in your MyLog class if you
want.

Of course you could stick to procedural style and split the manage_log
function in two to enhance readability and avoid passing message
strings around, but you are then forced to stick with one logfile
for sure, the name of which is stored in a global variable… unless
you start to rebuild the object system yourself or add yet another
parameter to each call to indicate which logfile to use.

Well, hope this helps. Just some things to think about.

-Michael


#3

On 07.12.2008 11:58, Tom C. wrote:

Am I missing something? Can anyone give me a compelling reason to write
fewer methods and more classes?

Interesting question and not easily answered - at least not in 10 words.

For me, the main advantage of OOP over procedural programming is
encapsulation - or to name a different term “abstract data types”: you
combine state (variables) and all the legal operations that can be
applied to it - excluding all illegal operations at the same time. This
leads to more robust code because, if all classes do only one thing and
do that well, you can more easily reuse the code and also the structure
is much easier to grasp for someone else (or for you, if you find you
need to change something a few months later).

Classes simply give you at least two more dimensions in which to
structure your code via encapsulation and inheritance. (Although I
personally feel that inheritance is overrated and often overused.)

If you are really interested in the matter and are ready to spend some
time (and money) I recommend reading “Object Oriented Software
Construction” by Bertrand Meyer (often called “OOSC”). It’s a big book
but you can read it one concept at a time. And although he writes
mostly about Eiffel (although it is mentioned at most once) he merely
talks about all the concepts related to OOP - which happen to be present
in Eiffel. IMHO Eiffel is the language which contains the richest set
of OO related features. BM certainly is among the guys on this planet
with the best understanding of what OO is about.

If anyone’s interested, the program to which I referred may be examined at

http://tomcloyd.com/misc/setnet.txt

An easy way to “find” your classes are CRC cards. “CRC” means “class
responsibility collaboration”. Basic idea is to identify things that
could be classes, write down their responsibilities and other classes
they should collaborate with.

If I were you I would at least create a class Database with all the
legal operations (e.g. open or read, close or write, add_relationship
etc.). I did not look closely enough to decide whether I would want to
have one database with all the nodes, relationships and links in it but
chances are that I would choose that approach. The reason is, that you
want one set of data which is consistent. (Btw, you could also build
your database on top of PStore which guarantees some transactional
consistency - you won’t be able to manipulate the DB via editor though.)

Maybe I would also have a class UserInterface which deals with all the
ways a user can interact with your Database. Looking at method
show_help this could be made easier (and more efficient at the same
time, although this is probably not important here) by placing all the
help messages in a Hash. I would also try to keep methods much shorter.
For example, you have a big main loop in method main where you do all
sorts of things some of which you could refactor to another method or
even class (parsing of the command line for example).

Kind regards

robert


#4

Michael,

Thanks very much. Very lucid and speaking to me right where I am. I get
it now.

This is the phrase that turned on the light for me “You’re building
excellent accessor methods to global variables (even though you are
using @instance_variable notation instead of $global_variable notation,
you only have one namespace in use so they are really just globals).”
It might help to explain my slowness to grasp things to mention that I
only just “got” instance variables. I’ve basically been writing
fortran/pascal in ruby. It was waaaay eaiser, and I was quite happy, but
I kept seeing other people doing those strange things which I didn’t
seem to have to do. Puzzling.

In posting here, I just knew someone would be able to nudge me over the
edge! I was probably too comfortable with what I was doing, which, while
incomplete at this point, seemed quite acceptable. The idea of building
in flexibility for the future by using classes is appealing.

So…I’ll recode it, now that I see why it’s worth the bother.

I truly appreciate your help!

t.


#5

Robert,

Wow. This, plus Michael’s contribution, gives me a lot to think about
and work on. Excellent! Rethinking my methods as little data processing
machines (which is how I’m currently thinking of classes), along the
lines you suggest, will clearly help me clean things up.

The idea of putting the messages in show_help into a hash is
interesting. At first I didn’t see the point, but then I see that it
would split out the data definition from the message generation, and
this task factoring clearly has advantages.

The CRC abstraction (which I can just do in an outline) is an excellent
notion. Thanks.

I had hoped this little project, which I expect to rapidly produce a
tool I’ll start using in many ways, would also move my programming
skills down the road. It’s happening. Couldn’t ask for more.

I seriously going to try to follow through on all the advice you and
Michael have give me. It all looks good.

As always, I’m very grateful for this list, and its great generosity.

Tom


#6

Oh, now THAT’s fun (and helpful). Thanks!

t.


#7

On Dec 7, 2008, at 3:58 AM, Tom C. wrote:

Am I missing something? Can anyone give me a compelling reason to
write fewer methods and more classes?

class YouCanTellThisStuffGoesTogether
end

class ThisDeclaresTheAtomsYouThinkAboutTheProblemIn
end

class ThisPreservesTheGlobalNamespace
end

class ThisGiveMeATypeForArgumentAndInterfaceChecking
end

class ThisProvidesAClearPlaceToChopTheProgramUpIntoFiles
end

class ThisReducesTheArgumentPassingByKeepingStateWithBehavior
end

class ThisAllowsMeToRefineAndSpecializeMethodsInSubclasses
end

class IsJustAnotherAbstractionLayerALongWithMethodsClosuresAndModules
end

class IsMisusedAndOverrated
end

module SomeTimesIsBetter
end

var = 42
closures_hide_information_too = lambda{ }

def even_methods_can
method(:even_methods_can).instance_variable_set ‘@static’, 42
end

one thing classes often fail to deliver on is making code more re-

usable, however they nearly always assist in making it re-editable,
which is vastly more important.

a @ http://codeforpeople.com/


#8

Nice addition to the discussion. I haven’t yet set up a module, but I’ve
been looking at it. Your point is well taken (assuming I correctly grasp
it). Thanks!

t.


#9

Hi –

On Sun, 7 Dec 2008, Tom C. wrote:

experience.
I’ve read a lot about them, but…here’s my question:

As I’ve puzzled about this for days, I’m very interested to see what better
informed people have to say about this question. Please understand that I do
grasp the basics, but do NOT see what the compelling reason is to use a class
in a reasonably simple program. Thanks!

I’ll just add to the answers you’ve already received by saying:
remember that classes are not the whole story behind a more
object-oriented approach. Objects are :slight_smile: There are ways you can
engineer objects that don’t necessarily use classes, but that do give
you the advantages of the kind of encapsulation and stylistic gains
that people have been talking about.

In particular, I’m thinking of modules, which can be used to add
functionality to a particular object as well as to all instances of a
particular class. And/or just defining one or more methods on a
particular object.

David