Searching CPAN for a module to help me manipulate a magnetic tape device , I discovered Mt version 0.0.1 : ) , Which is a wrapper for mt in perl. This is something I used to do constantly in my previous job IE make perlscripts that were 'aware' of things like fsf,bsf,bot,eod and would do a pretty good job of positioning the tape for appends, even to the point of abstracting the tape further away from the program, keeping a running index as the last element on tape AKA CiTransfer (if you've had the _pleasure_ )
What really struck me as odd though is that the CPAN Mt has only two methods, a constructor and a ->command method, which is passed a hash that describes
( -command=>'fsf etc here' , -count=>'some number', -args=>@arrayref );
If that's a wrapper , then what have I written? an interface ?. My module uses methods like ;
$tape->forward(2); $tape->rewind; $tape->positionforWrite; $tape->checkindex $tape->writeindex(@index);
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Talking to Magnetic Tapes
by Aristotle (Chancellor) on Oct 17, 2002 at 13:43 UTC | |
Makeshifts last the longest. | [reply] |
by submersible_toaster (Chaplain) on Oct 18, 2002 at 13:34 UTC | |
| [reply] |
by Aristotle (Chancellor) on Oct 18, 2002 at 13:46 UTC | |
Makeshifts last the longest. | [reply] |
Re: Talking to Magnetic Tapes
by submersible_toaster (Chaplain) on Oct 22, 2002 at 08:24 UTC | |
| [reply] [d/l] |
by Aristotle (Chancellor) on Oct 22, 2002 at 18:00 UTC | |
I assume you left the various warns in there just for development? The OS detection could be abstracted a bit further; some user control over it might not be a bad idea either. I'd also prefer if the commands produced Perlish boolean results, with an extra method to ask for the error code. I'd pull together the declaration of variables with their initial assignment in many places, though one might argue that's just preference. You could use the boolean results of matches in your stat method. And a map in void context?! :-) Some more abstraction would help. Note how your command routines all look almost the same. system LIST is usually better than system EXPR. Also, note how many of your routines call other command routines without checking intermediate results - not necessarily a good idea. The hardest to refactor was your stat routine (status in my version; your status is called get_status there). The following is untested due to lack of a magnetic tape. :-) It does compile properly at least. I left a couple of notes in a few places where I wasn't sure whether what you really meant.
Of course the POD will need some minor updates. :-) Oh, you might possibly want to consider changing your copyright information - the standard boilerplate is "This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself." If you don't want that, make sure your copyright legally really means the things you want it to mean. Makeshifts last the longest. | [reply] [d/l] |
Re: Talking to Magnetic Tapes
by submersible_toaster (Chaplain) on Oct 23, 2002 at 04:43 UTC | |
I found that this line in the constructor.
would create $self->{errorcmd} instead of setting error=>0 and cmd=>{hashstuff}
One thing that has put me into a tailspin is your use of $" and $/ . As an interesting aside, I think there is a misprint in Perl In a Nutshell-2ndEdition , whilst the index points to page 55 for global variable $" , page 55 claims the list separator is either $ or $LIST_SEPARATOR, no mention of $" - hmmm.
This will compile on perl5.6.1 , my poor Indy's/Octane's are still on 5.004 (something that will be remedied asap). I will read further into the behaviour of IPC::Open2 , I'm not certain yet but something is now breaking the get_index method. More on this as I investigate.
I think OO and hashes and nested data are slowly beginning to make sense to me.
Update : Have made some more modifications around some of the logic here, Aristotle wisely spoke of examining more closely the return values of each methodcall. I discovered that the lowerprecedence 'and' used in the position_for_write method was only calling one thing. Only ever executes 'endofdata' , whereas behaves as I would expect. Reading about 'or' vs '', '&&' vs 'and' didn't really explain this though. Update: More abstraction/less abstraction, I wonder about the needs for methodnames like backwardspace, forwardspace . Decided to catch-all the commands in %cmd via AUTOLOAD and execute them, applying this to Aristotle's code reduces to workhorses down to an execute method and the AUTOLOADer.
| [reply] [d/l] [select] |
by Aristotle (Chancellor) on Oct 31, 2002 at 22:01 UTC | |
More comments. $self{qw(error cmd)} is of course just a typo that was meant to be @self{qw(error cmd)}. I suspect the and vs && issue is due to my not using parens there. Writing $self->endofdata() probably would fix it - if it does, I'd prefer that version as I find and a lot more readable. I specifically didn't want the assertions block to return $ERROR, because then you can say
The intent in the second version is not readily discernible, and $tape is not a name for something I'd expect to find an error message in. Actually, the point in going through the whole hoopla of writing the _assert() function was to be able to easily provide Device::MagneticTape->error() for the calling code. The $self{os} block malfunctions because of the dummy entry in %os_specific_cmd and due to scalar context forced by the || after the block. That piece of code will need some unravelling to function correctly.. Not closing $rdh and $wrh in the status method shouldn't have any effect since they're lexicals - they go out of scope at the end of the function and are consequently autoclosed anyway. Is status behaving correctly? That's the one part of the code where I casted enough sorcery to be unsure whether it's bugfree with just a cursory look, but since as I said I don't have a tape drive I coudn't verify. Also, you are no longer calling execute from anywhere so you can roll it into AUTOLOAD. But as the module's user I would still like to have the long function names - I wouldn't want to have to learn the cryptic mt syntax. Besides, if this module is ever split to multiple backends so it can, f.ex, also control tapes on Windows with the native methods offered there, the mt syntax would be out of place. You want to offer your own consistent interface. But there's no reason why one shouldn't be able to do that using AUTOLOAD, and that way we also get rid of gotoend(). So, another round: Read more... (5 kB)
Please tell me how well these work.
Makeshifts last the longest. | [reply] [d/l] [select] |
by submersible_toaster (Chaplain) on Nov 04, 2002 at 03:44 UTC | |
Cool! - This _almost_ went through without a hitch Aristotle. But first with the changes I made. The os detection still needs some work, I think thatis assigning the number of grep matches to $os, rather than $_ from a successful match. The assignment to @self{qw(error cmd)} required an extra set of curly-ones to enclose the hashes that are combined into $self->{cmd}. Fixed one typo ->{status} NOT ->{_status}. Despite what I believe to be valid syntax, the chaining with and is not honoured - even with parens after the method calls, so sadly these read &&. Used the @args variable within the scope of _meta because map complained about 'trying to modify readonly value' , which I presume to be @_. AUTOLOAD's method detection I have maybe over engineered, by adding $class, the regex also modified with the + immediatly after the character class, as opposed to after the parens.. (this would match only one char otherwise). Read more... (5 kB) | [reply] [d/l] [select] |