Improving bad practice

J

Justin C

I stumbled across this web-page
<URL:http://http://perl-begin.org/tutorials/bad-elements>
and read the following:

Passing parameters in delegation
Sometimes we encounter a case where subroutines each pass the
same parameter to one another in delegation, just because the
innermost subroutines in the callstack need it.

To avoid it, create a class, and declare methods that operate
on the fields of the class, where you can assign the delegated
arguments.


I am definitely guilty of this. What I don't understand is the
explanation of how to avoid it. Can someone point me at some
simple examples or easy to comprehend documentation?

Justin.
 
R

Rainer Weikusat

Justin C said:
I stumbled across this web-page
<URL:http://http://perl-begin.org/tutorials/bad-elements>
and read the following:

Passing parameters in delegation
Sometimes we encounter a case where subroutines each pass the
same parameter to one another in delegation, just because the
innermost subroutines in the callstack need it.

To avoid it, create a class, and declare methods that operate
on the fields of the class, where you can assign the delegated
arguments.


I am definitely guilty of this. What I don't understand is the
explanation of how to avoid it.

Oh, that's easy: To avoid passing arguments, assign them to global
variables! To avoid getting flak for that, put all variables shared by a
set of subroutines into a hash (aka 'object instance') and pass that
around "by implicit delegation" using $self->other_method() instead.

NB: This piece of ill thought out advice is rather symptomatic for the
web page in question.
 
J

Justin C

NB: This piece of ill thought out advice is rather symptomatic for the
web page in question.

If it's ill thought out then I'll just ignore it!

Thank you for the reply.


Justin.
 
J

Justin C

Sorry, I've been meaning to make a proper reply...

No problem, there are no deadlines for replies. :)

The advice given (extremely poorly expressed) was to get rid of long
lists of parameters, many of which are simply passed down to subordinate
functions, by turning the functions into methods on some object and the
parameters into attributes. This is often good advice, but should not be
applied indiscriminately; there are often less radical changes to the
code which have as much benefit.

I understood it differently. I didn't think it suggested number of
parameters, but how many subs they/it are/is handed down through.
And possibly about calling subs from subs within subs within subs...

I'm still struggling with terminology in OO. I use OO perl all the
time (at least, I *think* that's what I'm doing! - mostly with CPAN
modules), but I'm finding it difficult to understand "turning the
functions into methods on some objects and parameters into
attributes".

Working in a more OO way will probably be beneficial to my under-
standing, I just don't see OO solutions to my everyday problems or
tasks. So while I might use OO with the modules I'm using, I tend
to write in a procedural way.

This is an example from something I'm working on at the moment.
[snip]

Most of the subordinate methods now just take a single parameter, and
pull out the information they need: I no longer need to keep track of
which methods take which arguments, and when I realise a method two or
three calls down needs a new parameter I don't have to change all the
intervening methods. Also, I have in fact already added a new parameter:
the _draw_accidental method needs 'current key signature' information
that wasn't passed before, but ->draw doesn't need to change to
accomodate that.

The next step is to turn the hashref into an object. As ever, this
should not be done 'just to be cool', but there are often concrete
advantages.

I'm sure there are instances in my code where I should do this, but
I don't always see when it would be useful. Right now I'm thinking
of some of my programs that create/write MS Excel. Module
SpreadSheet::WriteExcel uses OO methods, but I just iterate over
my data and pass it along all serialised. I should probably create
row objects, and cell objects which have content and formatting....
but there are many other situations, now I think about it, where
I should create objects out of my data.

If I turn my new $params parameter into a DrawCtx object, I can move
these methods into that class, like this:
[snip]

and again I've simplified the calling conventions because the object
already knows information that previously had to be passed in.

The final step in this sort of reorganisation would be to move the
drawing methods themselves into a Draw::Note class. That is, instead of
having a Note which knows how to draw itself and a DrawCtx which
represents the drawing parameters, I would have a Note object which just
holds the information about the note, a Draw::Note object which knows
how to draw one note, and a DrawCtx that knows how to build a Draw::Note
for a given Note.

Yup, I definitely need to think this way. Maybe if I finish the
Alpaca and/or Modern Perl I'll be better placed to work this way.

[snip]
The web page you quoted is telling you to jump straight to this step. I
wouldn't necessarily go straight there: it's quite a bit of extra
complexity just to avoid passing a single parameter around. I haven't
made this change yet in my code, though I am considering it, because it
separates 'model' (that is, the data we are representing) from 'view'
(the mechanism we are using to present that data to the user).

I've been reading about MVC in reference to Dancer, Mojolicious, and
Catalyst. It's one of the concepts I'm trying to get my head around.

This is a
useful thing to when there are several different ways to display the
same data: in my case, I can draw it on a window, I can write it to a
file, I can convert it into MIDI, and so on, and stuffing all the
methods for generating all these different representations into the
basic Note class results in a big unwieldy mess.

I think I should stop jumping in and writing code, and consider what
the problem is I'm trying to solve. Then write tools for a generic
situation rather than just the specific. I think this will get me code
that is more OO.

I've got some hideous DB stuff here. The first stuff I wrote, a cron
job on the DB server extracted data using SQL and emailed it to a
dummy user where procmail called perl to process the data. The next
gen of DB code used SSH, and now I've got an RPC server sitting on
the DB server and handling whatever my main working machine asks for

Hmm, that was rather long... I hope you got to the end, and it made some
sort of sense.

Yes, I got to the end. And I've been mulling it over all yesterday,
and a lot of today! Thank you for the comprehensive reply. It's
given me plenty to think about, and I need to think about such
things before I actually start writing code. I think I'm going to
be thinking about this for most of the rest of today too.


Justin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top