Your second code example works because the anonymous subs are within the same lexical scope; therefore, there is no need to store the variables they work with separately (in $self, like I did). Correct? I like that.

Precisely. And, if also notice, that second code example also is extremely similar to the way you're using your Hasher, but with a lot less overhead, more intuitive (I think), and no usage of $self.

The last block of code looks similar to mine, one of the differences being that you only call $self->filter($r) within the loop. Wouldn't the code within filter() be same difference to what I'm doing? That is, I still need an increment and a hashing, so filer() would contain ++$self->{count}; and so forth?

I see no evidence of not gaining understanding (understand that! ;-}); you nailed this one as well. The difference is that in the last block of code, the expectation is not that you'll give me coderefs from which I can call back to do stuff, but that you'll use inheritance to create a brand new package, and in that package, you'll name certain methods the names that I expect, and I'll call those as object methods at the appropriate places.

I believe I'm lost somewhere in between "This is only natural inside a single object, however your callbacks are all external to your object, so that doesn't make a bunch of sense to me." ...

Remember, like perl, English is context sensitive. (Sorry - I know it's the other way around, but it was funnier this way.) The context of this statement was talking about using "$self" inside callbacks - this is rarely done. Callbacks are generally done via closures in perl, and, because they're closures, they have access to all lexical variables at the point of their creation - if you need data to persist past the function call, you simply set it in your closure. For another example, see the File::Find module which uses this idea for the wanted routine.

... and "As in your filter object. Thus it makes perfect sense to modify object variables inside object methods, so you can do whatever you want with it." The latter statement says to me: "There are no closures (external thingies) involved, therefore everything happens within your methods," which makes me think "Well then, how do i keep this dynamic? Each filtering process is going to be 80% common, but there is some variation."

Dynamic - depends on how you want to do it. There are so many ways to do it that I can't really tell you what the best way is - it will depend on what you're trying to do, and the framework you're doing it in (both framework as in any object frameworks you may be using, such as POE, and framework as in how the rest of your code is laid out, the context, if you will.)

One way is to have different packages derived from your Filter package. You can then instantiate each one ("my $f = FilterThis->new()") and then execute it.

You can then find commonalities between each of your filter packages and push them into a new base class such that FilterThis is derived from CommonFilter which itself is derived from Filter. This is fine - I do this, and my Filter is actually dervied from Task, so you can keep going as much as you want. It's a little convoluted as a first foray into OO, but trust me, this provides a lot of flexibility.

Or, you can go simple - a halfway between procedural and OO. (Again, I may be an OO bigot, but this is often the right solution, so don't let my moniker scare you away from this option even while trying to learn OO.) This is to create a few packages derived from Filter, but each one would be drastically different from each other - any commonalities have been put into the filter function for each group. For example, if you were filtering a bunch of websites and a bunch of files, you could have three filter packages: FilterWebHTML, FilterWebXML, and FilterFlatFile. Then, when you create each one, you pass in the variable that applies, e.g., my $f = FilterWebXML->new('http://www.perlmonks.org/index.pl?displaytype=xml;node_id=3333'). You can create lots of each type of object which filters differently from each other, but have the commonality split out based on logic (HTML, XML, Flat files are all filtered differently) vs parameters (the location of each file).

my @htmls = qw( ... ); my @xmls = qw( ... ); my @flats = qw( ... ); my @filters; push @filters, map { FilterWebHTML->new($_) } @htmls; push @filters, map { FilterWebXML->new($_) } @xmls; push @filters, map { FilterFlatFile->new($_) } @flats; $_->perform_filter() for @filters;
And in the new method, you just have to store the filename/URL to be filtered in $self somewhere.


In reply to Re^5: OOP first-timer seeks feedback; likes long walks on the beach. by Tanktalus
in thread OOP first-timer seeks feedback; likes long walks on the beach. by eff_i_g

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.