http://www.perlmonks.org?node_id=1208811

Discipulus has asked for the wisdom of the Perl Monks concerning the following question:

Greetings nuns and monks,

I'm still wondering how my module should look like: the module was announced here but I just received one comment, a precious one by Anonymous Monk, but in my reply I planned a bit more of abstraction probably worth to be implemented. I ask here, and no to the above mentioned thread, because it seems to me a separate question.

So the actual plan is to have a generalist Win32::Event::Engine module which can trigger any type of action instead of just write to a logfile.

So I plan to separate the event reading part and put it or as a subclass of the above or as a separate module on it's own. Which option seems more appropriate?

Then for the reader module I want to provide a simple wrapper around Win32::EventLog as default and optionally, instead of this, a wrapper around the wevtutil.exe that is difficult to use per se and can access even exotic events registries (as told in the OP too).

Should I create a Win32::EventReader as empty class having two separate modules like Win32::EventReader::EventLog (using the Win32::EventLog already existing module) and Win32::EventReader::Wevtutil (using the warpper around the system call)?

Or Win32::EventReader using by default Win32::EventLog and a subclass Win32::EventReader::Wevtutil ? In this case how to manage the user choice? An option in the constructor that replace the current new call with a subclass one?

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re: subclassing: how to design my module
by stevieb (Canon) on Feb 09, 2018 at 15:11 UTC

    Congratulations Discipulus!

    Without seeing an overview of all the various pieces, it's hard to come up with the best scenario here, so anything I say here is just off the top of my head.

    In Win32::Event2Log, you could use the Engine as a base class, and in the Engine, you could use (or optionally require at runtime depending on the user's selection). Then, for example, if a user wants a specific "type" (ie. Reader, or wrapper for the binary):

    my $obj = Win32::Event2Log->new(engine => 'type');

    Then, in the constructor above:

    use 'base' Win32::Event2Log::Engine; sub new { my ($class, %args) = @_; my $self = bless {%args}, $class; # select_engine inherited return $self->select_engine($self->{engine}); }

    In Engine

    use Win32::Event2Log::Reader; use Win32::Event2Log::Wevtutil; sub select_engine { shift; # throw away Event2Log object, unless needed/wanted my ($engine) = @_; my %engines = ( reader => sub { return Win32::Event2Log::Reader->new(...); }, wrapper => sub { return Win32::Event2Log::Wevtutil->new(...); +}, ); $engines{$engine}->(); }

    Very much untested, and again, I'm a bit confused as to how the whole thing ties together, so this is just one example of what can be done here. If you add more functionality in the future, you'd just need to modify Engine, as the Event2Log module simply passes the "type" along as an argument. Engine can take care of managing the actual engines, as it probably should.

Re: subclassing: how to design my module
by Anonymous Monk on Feb 11, 2018 at 03:14 UTC

    Engine is a stop word :) its like using "Wheel" or program/module...

    Subclassing not required or beneficial as there are only 2 things that read event logs, win32api and win32exe

    Win32::EventsFilter Win32::EventsFilter::EventLog Win32::EventsFilter::Wevtutil Win32::Events Win32::Events::EventLog Win32::Events::Wevtutil Win32::Evt Win32::Evt::EventLog Win32::Evt::Wevtutil sub Win32::Evt::start { ... } sub Win32::Evt::EventLog::Last { ... } sub Win32::Evt::Wevtutil::Last { ... } sub Win32::Evt::EventLog::GetNth { ... } sub Win32::Evt::Wevtutil::GetNth { ... }

    Ok, if you really wanna gotta subclass, do it without inheritance, and with style (the name not the noises)

    package Win32::Evt::Darllenydd; use Moo::Role; requires 'Last', 'GetNth', ...; no Moo::Role; package Win32::Evt::EventLog; use Moo; with 'Win32::Evt::Darllenydd'; sub Win32::Evt::EventLog::Last { ... } sub Win32::Evt::EventLog::GetNth { ... } no Moo; ...

    ok ok, if you really really want inheritance

    use parent 'Win32::Evt::Darllenydd'; ... package Win32::Evt::Darllenydd; use Carp(); sub Last { Carp::croak( "Last unimplemented" ); } sub GetNth{ Carp::croak( "GetNth unimplemented" ); } ...

     

    Hmm vanity .... delicious

    Win32::DiEvt Win32::DiEvt::EventLog Win32::DiEvt::Wevtutil