Re: Simple multi-level tie
On Tue, Jan 06, 2004 at 01:00:36PM -0600, david nicol wrote: > that works too. The first time I worked with dbm files, it was > with an implementation that produced both a .pag and a .dir file > for a database, so there was no one data file to lock. If I just use > C and let Perl select an implementation, I don't know what > the file name is going to be. It could be foo, it could be foo.db, it > could be both foo.dir and foo.pag. So if I use foo.advisory_lock for > the advisotyr lock, I'm safe regardless of implementation. I'm also > safe from the implementation needing the flock bits if it uses them. > I don't know that they do, but I also don't know that they don't. > > Also what would happen if you got your lockfile open syntax wrong > and accidentally clobbered your data? > > So I consider using a separate advisory file a best practice. I > have never done a performance comparison, but owuld be curious to see > one. A splendid explanation. Thanks for that. Consider me convinced :-) Mx.
Re: Simple multi-level tie
* david nicol <[EMAIL PROTECTED]> [2004-01-06 20:03]: > I'm also safe from the implementation needing the flock bits if > it uses them. I don't know that they do, but I also don't know > that they don't. You're also safe because tieing and locking is not an atomic operation, and some DBM libraries modify the file as soon as they open it. tieing first and locking the DBM afterwards would create a race condition. -- Regards, Aristotle "If you can't laugh at yourself, you don't take life seriously enough."
Re: Simple multi-level tie
On Mon, 2004-01-05 at 07:03, Martyn J. Pearce wrote: > On Mon, Dec 22, 2003 at 05:41:27PM -0600, david nicol wrote: > > > > open advisory file > > lock advisory file (shared for reading, exclusive for writing) > > tie data file > > access data file > > untie data file > > unlock advisory file > > close advisory file > Why the advisory file? I mean, why not lock the data file directly? > > Mx. that works too. The first time I worked with dbm files, it was with an implementation that produced both a .pag and a .dir file for a database, so there was no one data file to lock. If I just use C and let Perl select an implementation, I don't know what the file name is going to be. It could be foo, it could be foo.db, it could be both foo.dir and foo.pag. So if I use foo.advisory_lock for the advisotyr lock, I'm safe regardless of implementation. I'm also safe from the implementation needing the flock bits if it uses them. I don't know that they do, but I also don't know that they don't. Also what would happen if you got your lockfile open syntax wrong and accidentally clobbered your data? So I consider using a separate advisory file a best practice. I have never done a performance comparison, but owuld be curious to see one. -- david nicol "Take your time." -- Allan Quaterman
Re: Simple multi-level tie
On Mon, Dec 22, 2003 at 05:41:27PM -0600, david nicol wrote: > A similar negative experience got me in the habit of being strict > with locking discipline when using DBM. > > open advisory file > lock advisory file (shared for reading, exclusive for writing) > tie data file > access data file > untie data file > unlock advisory file > close advisory file > > if you can queue up database activity, you can do more than one > in the "access data file" section; otherwise you need to do all > these steps to safely use a local hashed file. David, Why the advisory file? I mean, why not lock the data file directly? Mx.
Re: Simple multi-level tie
On Fri, 2003-12-19 at 22:26, Terrence Brannon wrote: > > I quit using DBM files after one corrupted on me during an aborted > write. A similar negative experience got me in the habit of being strict with locking discipline when using DBM. open advisory file lock advisory file (shared for reading, exclusive for writing) tie data file access data file untie data file unlock advisory file close advisory file if you can queue up database activity, you can do more than one in the "access data file" section; otherwise you need to do all these steps to safely use a local hashed file. -- david nicol The elves have left the building
Re: Simple multi-level tie
Andrew Sterling Hanenkamp wrote: use Storable qw(freeze thaw); use Tie::HashWrapper; tie my %wrappee, 'AnyDBM_File', ...; tie my %hash, 'Tie::HashWrapper', \%wrappee, -inflate_value => sub { thaw(shift) }, -deflate_value => sub { freeze(shift) }; $hash{a}{complicated}[4]{data} = [ 'structure' ]; I quit using DBM files after one corrupted on me during an aborted write. I suppose I could have simply copied the dbm before and after all my operations, but with the advent of transaction-safe DBD::SQLite and the ever-presence of DBIx::Tree, I feel much more comfortable just tossing my complicated data in a RDBMS and pulling it out.
Re: Simple multi-level tie
Okay, so I ended up having more time last night than I thought I would. I finished Tie::Filter and the filter packages for scalars, arrays, and hashes. I've decided to hold off on writing one for handles as it is a significantly more complicated problem--and it might be better as an IO:: class. Anyway, the dist is named Tie-Filter-1.02 and it's been indexed at http://search.cpan.org/~hanenkamp/Tie-Filter-1.02/ so feel free to take a look at make suggestions. Regards, Sterling On Wed, 2003-12-17 at 14:00, Andrew Sterling Hanenkamp wrote: > I would like the ability to store a complicated record inside of a DBM > file. I looked in the usual places and perldoc -q DBM gives me: > > Either stringify the structure yourself (no fun), or else get > the MLDBM (which uses Data::Dumper) module from CPAN and layer > it on top of either DB_File or GDBM_File. > > Therefore, I went in search of a solution to automate the > stringification. I didn't find anything other than MLDBM for doing > something like this and it seems like a little much for my purposes. All > I need is something like this: > > $hash{name} = "value1:value2:value3:..."; > > I've done some work with Tie::Memoize and really like it's interface, so > I decided to write something like it for wrapping hashes. Thus, > Tie::HashWrapper was born. It may be used like this: > > tie my %wrappee, 'AnyDBM_File', ...; > tie my %wrapper, 'Tie::HashWrapper', \%wrappee, > -deflate_value => sub { join ':', @{$_[0]} }, > -inflate_value => sub { split /:/, $_[0] }; > > $wrapper{name} = [ value1, value2, value3 ]; > > and so forth. In addition, if one wants to have more complicated keys, > one may add -deflate_key/-inflate_key values to the call to tie. I > haven't uploaded it CPAN yet pending documentation and finding a good > name. > > Does Tie::HashWrapper seem reasonable? Or does anyone have a better > name? Have I gone off the deep-end again and rewritten something that > already exists and I missed it? > > Cheers, > Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Myth: Linux has a lower TCO Fact: If you consider that buying NT licenses for business use is tax-deductible, as are all those tech support calls, NT actually has a lower TCO than Linux! How are you going to expense software that doesn't cost anything? Eh?!? -- From a LinuxToday post
Re: Simple multi-level tie
On Thu, 2003-12-18 at 14:11, A. Pagaltzis wrote: > I like them better as well, but I think (in|de)flate is too > specific considering the generic nature of these filtering tie > modules. I can't think of any better terminology of my own; maybe > it would be best to simple reuse the names we're already familiar > with in Perl: (FETCH|STORE)(KEY|VALUE)?. me too (is this list averse to me toos? I am new here) -- david nicol The elves have left the building
Re: Simple multi-level tie
> What I want to know is, is Tie::HashWrapper a good name? If you don't > like that name, what might you call it? HashWrapper sounds kind of dorky > to me, but that's what first came to mind and I didn't want to spend all > day trying to name it, I wanted to play code monkey. > > Cheers, > Sterling I think Tie::HashWrapper is a fine name for a module that wraps a hash in a to-be-declared layer. You could get cute and call it Blintz or Burrito or something. Maybe "zigzag." -- david nicol perl -e 'printf "ah, hot %x.\n", 12648430'
Re: Simple multi-level tie
On Wed, 2003-12-17 at 23:25, Andrew Sterling Hanenkamp wrote: > tie my %hash, 'Tie::HashWrapper', \%wrappee, > -inflate_value => sub { thaw(shift) }, > -deflate_value => sub { freeze(shift) }; > $hash{a}{complicated}[4]{data} = [ 'structure' ]; warning: the above will not autovivify. $hash{a} will get a reference to an empty hash stored in it, then the empty hash will get {complicated} added to it, etc. DirDB deals with this by hijacking empty hash references and tieing them too. -- david nicol perl -e 'printf "ah, hot %x.\n", 12648430'
Re: Simple multi-level tie
On Thu, 2003-12-18 at 14:11, A. Pagaltzis wrote: > I do, because for simple one-off uses, the standard mechanism > requires too much baggage. Sometimes I'd like to use tieing in a > 10-line script; not having to create a package and populate it > with a half dozen subs, which is alone 15 lines of red tape - > that would be neat. > > But then, this is Tie::Filter, not Tie::Simple, and I agree it > doesn't really fall in the scope of this module suite. Well, unless I have need for or have some spare time, I think I'll stick to just Tie::Filter for now. ;) > You could DWIM on the type of variable you're tying to (or the > type of variable you're wrapping, which is the same), so people > could just say 'Tie::Filter' and have their variables tied to an > object of the right class. I must confess that I was not aware of the term DWIM. Thank goodness for the Camel book and thanks again goes out to Christiansen, Wall, Orwant, and Schwartz. I think that's an excellent idea. > I like them better as well, but I think (in|de)flate is too > specific considering the generic nature of these filtering tie > modules. I can't think of any better terminology of my own; maybe > it would be best to simple reuse the names we're already familiar > with in Perl: (FETCH|STORE)(KEY|VALUE)?. Hmmm...I think you are right about INFLATE/DEFLATE being too specific. Though, I'm not certain I like FETCH/STORE either as these are not the operations being performed. As a parallel to DBM filters, I just looked at their names again and they are: filter_(fetch|store)_(key|value). So, your suggestion fits to an extent. To carry the parallel the rest of the way we have FILTER(FETCH|STORE)(KEY|VALUE)?. But the names we get are hideous. A better solution than this would be FILTER_(FETCH|STORE)(KEY|VALUE)? as our brains can still process that in a quick scan. Still, I don't like it. I think I'll use the names (FETCH|STORE)(KEY|VALUE)? anyway as I don't like the names that start with FILTER_. Anyone object? I could do it both ways, TMTOWTDI, but I don't know if that's appropriate either. I'm actively working on this project right now, but won't be ready to post it on CPAN until at least tomorrow afternoon. Due to the wonders of :%s/// in Vim, I can change anything until then if the consensus is different. I really appreciate all the help. Cheers, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] "When an opponent declares, 'I will not come over to your side,' I calmly say, 'Your child belongs to us already...What are you? You will pass on. Your descendants, however, now stand in the new camp. In a short time they will know nothing else but this new community.'" -- Adolf Hitler, on public education.
Re: Simple multi-level tie
* Andrew Sterling Hanenkamp <[EMAIL PROTECTED]> [2003-12-18 19:02]: > However, at this point, this project is becoming far more serious than > the original idea Which is always good when code's meant to go onto CPAN :-) > The wrapped object must be of the same type as the tie itself > since the Tie::Filter class does the work of actually > manipulating the internal object. (Becoming any more general > and we've just invented a new way of implementing a tied object > and I don't really think that's necessary.) I do, because for simple one-off uses, the standard mechanism requires too much baggage. Sometimes I'd like to use tieing in a 10-line script; not having to create a package and populate it with a half dozen subs, which is alone 15 lines of red tape - that would be neat. But then, this is Tie::Filter, not Tie::Simple, and I agree it doesn't really fall in the scope of this module suite. > Tie::Filter::Scalar: > > tie $scalar, 'Tie::Filter::Scalar', \$wrapped, > INFLATE => sub { ... }, > DEFLATE => sub { ... }, > > Tie::Filter::Array: > > tie @array, 'Tie::Filter::Array', [EMAIL PROTECTED], > INFLATE => sub { ... }, > DEFLATE => sub { ... }; > > Tie::Filter::Hash: > > tie %hash, 'Tie::Filter::Hash', \%wrapped, > INFLATEKEY => sub { ... }, > DEFLATEKEY => sub { ... }, > INFLATEVALUE => sub { ... }, > DEFLATEVALUE => sub { ... }; > > Tie::Filter::Handle: > > tie $handle, 'Tie::Filter::Handle', \$handle, > INFLATE => sub { ... }, # stream read > DEFLATE => sub { ... }; # stream write You could DWIM on the type of variable you're tying to (or the type of variable you're wrapping, which is the same), so people could just say 'Tie::Filter' and have their variables tied to an object of the right class. > I think I like these keys better than the -inflate*/-deflate* > ones I presented before. I like them better as well, but I think (in|de)flate is too specific considering the generic nature of these filtering tie modules. I can't think of any better terminology of my own; maybe it would be best to simple reuse the names we're already familiar with in Perl: (FETCH|STORE)(KEY|VALUE)?. -- Regards, Aristotle "If you can't laugh at yourself, you don't take life seriously enough."
Re: Simple multi-level tie
* Andrew Sterling Hanenkamp <[EMAIL PROTECTED]> [2003-12-18 20:01]: > I think I lean towards the modification of $_ in-place as it > seems a little more Perlesque. Given the name Tie::Filter, I'd agree. -- Regards, Aristotle "If you can't laugh at yourself, you don't take life seriously enough."
Re: Simple multi-level tie
Andrew Sterling Hanenkamp <[EMAIL PROTECTED]> wrote > use Storable qw(freeze thaw); > use Tie::HashWrapper; > > tie my %wrappee, 'AnyDBM_File', ...; > tie my %hash, 'Tie::HashWrapper', \%wrappee, > -inflate_value => sub { thaw(shift) }, > -deflate_value => sub { freeze(shift) }; Or rather more Perlishly -inflate_value => \&thaw, -deflate_value => \&freeze }; > $hash{a}{complicated}[4]{data} = [ 'structure' ]; Mike Guy
Re: Simple multi-level tie
Another question I want to add to my proposal is: should the code references work by modifying $_ in-place (as with DBM filters) or should the code take an argument and return a result. I think I lean towards the modification of $_ in-place as it seems a little more Perlesque. Cheers, Sterling On Thu, 2003-12-18 at 12:01, Andrew Sterling Hanenkamp wrote: > I would like to revise my original query into a proposal in light of the > comments I've received to now suggest a Tie::Filter namespace for > filtering Tie classes. There could be specialized classes > Tie::Filter::Scalar, Tie::Filter::Array, Tie::Filter::Hash, and > Tie::Filter::Handle. > > However, at this point, this project is becoming far more serious than > the original idea and I think I'm going to need an actual design for > each of these. The implementations will all be tiny, but I want an > interface that seems natural. Really, the only API that these modules > have to come up with are the arguments to tie, so I propose the > following syntax for calls to tie: > > For all Tie::Filter classes, the first argument will always be a > reference to the wrapped object. The wrapped object must be of the same > type as the tie itself since the Tie::Filter class does the work of > actually manipulating the internal object. (Becoming any more general > and we've just invented a new way of implementing a tied object and I > don't really think that's necessary.) > > Tie::Filter::Scalar: > > tie $scalar, 'Tie::Filter::Scalar', \$wrapped, > INFLATE => sub { ... }, > DEFLATE => sub { ... }, > > Tie::Filter::Array: > > tie @array, 'Tie::Filter::Array', [EMAIL PROTECTED], > INFLATE => sub { ... }, > DEFLATE => sub { ... }; > > Tie::Filter::Hash: > > tie %hash, 'Tie::Filter::Hash', \%wrapped, > INFLATEKEY => sub { ... }, > DEFLATEKEY => sub { ... }, > INFLATEVALUE => sub { ... }, > DEFLATEVALUE => sub { ... }; > > Tie::Filter::Handle: > > tie $handle, 'Tie::Filter::Handle', \$handle, > INFLATE => sub { ... }, # stream read > DEFLATE => sub { ... }; # stream write > > I think I like these keys better than the -inflate*/-deflate* ones I > presented before. > > Any other suggestions? I'll keep working on this and am glad to take any > other suggestions. Thank you all for your suggestions; they have been > very helpful. > > Regards, > Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Microsoft is a cross between the Borg and the Ferengi. Unfortunately, they use Borg to do their marketing and Ferengi to do their programming. -- Simon Slavin
Re: Simple multi-level tie
I would like to revise my original query into a proposal in light of the comments I've received to now suggest a Tie::Filter namespace for filtering Tie classes. There could be specialized classes Tie::Filter::Scalar, Tie::Filter::Array, Tie::Filter::Hash, and Tie::Filter::Handle. However, at this point, this project is becoming far more serious than the original idea and I think I'm going to need an actual design for each of these. The implementations will all be tiny, but I want an interface that seems natural. Really, the only API that these modules have to come up with are the arguments to tie, so I propose the following syntax for calls to tie: For all Tie::Filter classes, the first argument will always be a reference to the wrapped object. The wrapped object must be of the same type as the tie itself since the Tie::Filter class does the work of actually manipulating the internal object. (Becoming any more general and we've just invented a new way of implementing a tied object and I don't really think that's necessary.) Tie::Filter::Scalar: tie $scalar, 'Tie::Filter::Scalar', \$wrapped, INFLATE => sub { ... }, DEFLATE => sub { ... }, Tie::Filter::Array: tie @array, 'Tie::Filter::Array', [EMAIL PROTECTED], INFLATE => sub { ... }, DEFLATE => sub { ... }; Tie::Filter::Hash: tie %hash, 'Tie::Filter::Hash', \%wrapped, INFLATEKEY => sub { ... }, DEFLATEKEY => sub { ... }, INFLATEVALUE => sub { ... }, DEFLATEVALUE => sub { ... }; Tie::Filter::Handle: tie $handle, 'Tie::Filter::Handle', \$handle, INFLATE => sub { ... }, # stream read DEFLATE => sub { ... }; # stream write I think I like these keys better than the -inflate*/-deflate* ones I presented before. Any other suggestions? I'll keep working on this and am glad to take any other suggestions. Thank you all for your suggestions; they have been very helpful. Regards, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Keep me informed on the behaviour of this kernel.. As the "BugFree(tm)" series didn't turn out too well, I'm starting a new series called the "ItWorksForMe(tm)" series, of which this new kernel is yet another shining example. -- Linus, in the announcement for 1.3.29
Re: Simple multi-level tie
On Thu, 2003-12-18 at 04:26, Tim Bunce wrote: > I'd add a -1 to the split and not in the docs that the example > won't handle undefs. Fine. The example is relatively close to what I need the package for, but as a general example it's probably a poor one. > I didn't like it at first but the more I try to think of alternatives, > and understand the purpose and use, the more I like it. > > A key point is that although it was created for inflating/deflating > values, there's no need to use it for that. It does 'wrap' access to > the underlying hash and that wrapping can be used for other purposes, > including logging or recording where/how the hash is used. Yes, I believe I mistated the utility of the module in my original post. I should have been more careful to state this possiblity up front. > > It's similar in some ways to: > http://search.cpan.org/~pmqs/BerkeleyDB-0.25/BerkeleyDB.pod#DBM_Filters > > And I think it would be worth making it more similar. Consider > > tie my %wrapper, 'Tie::HashWrapper', \%wrappee, > store_key => sub { lc(shift) }, > store_value => sub { join ':', @{$_[0]} }, > fetch_value => sub { lc(shift) }, > fetch_key => sub { split /:/, $_[0], -1 }; > > Tim. > > p.s. I trust your tests cover things like FIRSTKEY, NEXTKEY, DELETE etc. Well, the tests are hardly written as of now. They cover all tied hash operations, but very poorly. I plan on writing more robust tests before releasing it. Regards, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Keep me informed on the behaviour of this kernel.. As the "BugFree(tm)" series didn't turn out too well, I'm starting a new series called the "ItWorksForMe(tm)" series, of which this new kernel is yet another shining example. -- Linus, in the announcement for 1.3.29
Re: Simple multi-level tie
On Thu, 2003-12-18 at 05:59, A. Pagaltzis wrote: > I'd prefer if it didn't (ab)use the "minus on literal string". > There's nothing ambiguous in the syntax that might require it. I disagree, since the tie call could include -inflate_key and -deflate_value. It is also legal to say: tie %hash, 'Tie::HashWrapper', \%wrapped, sub { ... }, # -inflate_key sub { ... }, # -deflate_key sub { ... }, # -inflate_value sub { ... }; # -deflate_value This is all using my own Getargs::Mixed module. > Sounds like what you're proposing is a special case of a > simplified interface to tieing in general. You're making life > easier for dealing with tied hashes by only having to deal with > the values. But it isn't necessary for the approach to be > specific to hashes. With appropriate pass-through from of > parameters from FETCH and STORE, it would apply to any kind of > tie. > > So I propose Tie::Simple as a collective namespace for generic > modules that offer a simplified interface to tieing and > Tie::Simple::Hash for this one. I like this idea. When I was writing this I had thought that it might be useful to have such a module for arrays, scalars, and handles. However, I think Tie::Filter might be a better namespace. > > A reason for this proposal is that I wouldn't use this module to > roll my own, like you're attempting; contrary to your sentiment, > I'd use MLDBM. I've used it before, and while it's a big wheel, > it also affords me the comfort of being able to change to a > different data structure, particularly to a more complex one, > instantly, should my needs ever expand. But there's need, IMO, > for a module that makes quick one-off uses of the tie mechanism > simpler than the cumbersome logistics required by vanilla Perl. > > So that's what I believe would be a good goal to aim for. Regards, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Keep me informed on the behaviour of this kernel.. As the "BugFree(tm)" series didn't turn out too well, I'm starting a new series called the "ItWorksForMe(tm)" series, of which this new kernel is yet another shining example. -- Linus, in the announcement for 1.3.29
Re: Simple multi-level tie
* Andrew Sterling Hanenkamp <[EMAIL PROTECTED]> [2003-12-17 21:03]: > I've done some work with Tie::Memoize and really like it's > interface, so I decided to write something like it for wrapping > hashes. Thus, Tie::HashWrapper was born. It may be used like > this: > > tie my %wrappee, 'AnyDBM_File', ...; > tie my %wrapper, 'Tie::HashWrapper', \%wrappee, > -deflate_value => sub { join ':', @{$_[0]} }, > -inflate_value => sub { split /:/, $_[0] }; > > $wrapper{name} = [ value1, value2, value3 ]; I'd prefer if it didn't (ab)use the "minus on literal string". There's nothing ambiguous in the syntax that might require it. > Does Tie::HashWrapper seem reasonable? Or does anyone have a > better name? Have I gone off the deep-end again and rewritten > something that already exists and I missed it? Sounds like what you're proposing is a special case of a simplified interface to tieing in general. You're making life easier for dealing with tied hashes by only having to deal with the values. But it isn't necessary for the approach to be specific to hashes. With appropriate pass-through from of parameters from FETCH and STORE, it would apply to any kind of tie. So I propose Tie::Simple as a collective namespace for generic modules that offer a simplified interface to tieing and Tie::Simple::Hash for this one. A reason for this proposal is that I wouldn't use this module to roll my own, like you're attempting; contrary to your sentiment, I'd use MLDBM. I've used it before, and while it's a big wheel, it also affords me the comfort of being able to change to a different data structure, particularly to a more complex one, instantly, should my needs ever expand. But there's need, IMO, for a module that makes quick one-off uses of the tie mechanism simpler than the cumbersome logistics required by vanilla Perl. So that's what I believe would be a good goal to aim for. -- Regards, Aristotle "If you can't laugh at yourself, you don't take life seriously enough."
Re: Simple multi-level tie
On Wed, Dec 17, 2003 at 02:00:23PM -0600, Andrew Sterling Hanenkamp wrote: > I would like the ability to store a complicated record inside of a DBM > file. I looked in the usual places and perldoc -q DBM gives me: > > Either stringify the structure yourself (no fun), or else get > the MLDBM (which uses Data::Dumper) module from CPAN and layer > it on top of either DB_File or GDBM_File. > > Therefore, I went in search of a solution to automate the > stringification. I didn't find anything other than MLDBM for doing > something like this and it seems like a little much for my purposes. All > I need is something like this: > > $hash{name} = "value1:value2:value3:..."; > > I've done some work with Tie::Memoize and really like it's interface, so > I decided to write something like it for wrapping hashes. Thus, > Tie::HashWrapper was born. It may be used like this: > > tie my %wrappee, 'AnyDBM_File', ...; > tie my %wrapper, 'Tie::HashWrapper', \%wrappee, > -deflate_value => sub { join ':', @{$_[0]} }, > -inflate_value => sub { split /:/, $_[0] }; > $wrapper{name} = [ value1, value2, value3 ]; I'd add a -1 to the split and not in the docs that the example won't handle undefs. > Does Tie::HashWrapper seem reasonable? Or does anyone have a better > name? Have I gone off the deep-end again and rewritten something that > already exists and I missed it? I didn't like it at first but the more I try to think of alternatives, and understand the purpose and use, the more I like it. A key point is that although it was created for inflating/deflating values, there's no need to use it for that. It does 'wrap' access to the underlying hash and that wrapping can be used for other purposes, including logging or recording where/how the hash is used. It's similar in some ways to: http://search.cpan.org/~pmqs/BerkeleyDB-0.25/BerkeleyDB.pod#DBM_Filters And I think it would be worth making it more similar. Consider tie my %wrapper, 'Tie::HashWrapper', \%wrappee, store_key => sub { lc(shift) }, store_value => sub { join ':', @{$_[0]} }, fetch_value => sub { lc(shift) }, fetch_key => sub { split /:/, $_[0], -1 }; Tim. p.s. I trust your tests cover things like FIRSTKEY, NEXTKEY, DELETE etc.
RE: Simple multi-level tie
I actually like names that sound like food On a slightly more serious note---If I were looking for stringification, I wouldn't be looking under HashWrapper. Perhaps Tie::HashStringify or the like? --hsm > -Original Message- > From: Andrew Sterling Hanenkamp [mailto:[EMAIL PROTECTED] > Sent: Wednesday, December 17, 2003 1:00 PM > To: Module Authors > Subject: Simple multi-level tie > > > I would like the ability to store a complicated record inside of a DBM > file. I looked in the usual places and perldoc -q DBM gives me: > > Either stringify the structure yourself (no fun), or else get > the MLDBM (which uses Data::Dumper) module from CPAN and layer > it on top of either DB_File or GDBM_File. > > Therefore, I went in search of a solution to automate the > stringification. I didn't find anything other than MLDBM for doing > something like this and it seems like a little much for my purposes. All > I need is something like this: > > $hash{name} = "value1:value2:value3:..."; > > I've done some work with Tie::Memoize and really like it's interface, so > I decided to write something like it for wrapping hashes. Thus, > Tie::HashWrapper was born. It may be used like this: > > tie my %wrappee, 'AnyDBM_File', ...; > tie my %wrapper, 'Tie::HashWrapper', \%wrappee, > -deflate_value => sub { join ':', @{$_[0]} }, > -inflate_value => sub { split /:/, $_[0] }; > > $wrapper{name} = [ value1, value2, value3 ]; > > and so forth. In addition, if one wants to have more complicated keys, > one may add -deflate_key/-inflate_key values to the call to tie. I > haven't uploaded it CPAN yet pending documentation and finding a good > name. > > Does Tie::HashWrapper seem reasonable? Or does anyone have a better > name? Have I gone off the deep-end again and rewritten something that > already exists and I missed it? > > Cheers, > Sterling > > -- > <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> > Andrew Sterling Hanenkamp > http://Andrew.Sterling.Hanenkamp.com/ > [EMAIL PROTECTED] / [EMAIL PROTECTED] > > There exists in the human heart a depraved taste for equality, which > impels the weak to attempt to lower the powerful to their own level, > and reduces men to prefer equality in slavery to inequality under > freedom. -- Alexis de Tocqueville >
Re: Simple multi-level tie
On 12/18/2003 12:25 AM, Andrew Sterling Hanenkamp wrote: "Wrapping hashes with arbitrary inflate/deflate methods." This is a tool that adds syntactic sugar to hashes. I developed it for the purpose of making complicated storage in hashes tied to DBM files nicer. It doesn't matter if you use CGI::query_string, Storable, join/split, pack/unpack, or even just use this to do some kind of wacky filtering, this tool isn't a marshalling tool, it is a syntax helper. What I want to know is, is Tie::HashWrapper a good name? If you don't like that name, what might you call it? HashWrapper sounds kind of dorky to me, but that's what first came to mind and I didn't want to spend all day trying to name it, I wanted to play code monkey. It's a horrible name. Sorry. :-) The name needs to say what it is or what it's for, not how it's done. Some people hate the Tie namespace (I'm one of them), but it has become "standard" for tied modules. So: Tie::MLDBM::Any_* (something) or Tie::MLDBM::Custom_* (something) where * says something about having custom marshalling methods. (Store|Marshall|Format|Dump|Load|Stow|...) Regards, Randy.
Re: Simple multi-level tie
On Wed, 2003-12-17 at 17:15, david nicol wrote: > As I understand it, the "standard" way to (de)marshall things anymore > is to use Storable. see DirDB::Storable for an example of a multi-level > tie that punts anything other than scalars and unblessed hashrefs to > Storable for nstorage and retreival. This is yet another corollary to my solution. If you like Storable then: use Storable qw(freeze thaw); use Tie::HashWrapper; tie my %wrappee, 'AnyDBM_File', ...; tie my %hash, 'Tie::HashWrapper', \%wrappee, -inflate_value => sub { thaw(shift) }, -deflate_value => sub { freeze(shift) }; $hash{a}{complicated}[4]{data} = [ 'structure' ]; > > If you're not going to have more than a thousand records (or you > have reiserfs) DirDB might be the module for you rather than a > single-file database. Ah, Hubris, Randall Schwartz and the Great One would be proud. ;) Alas, either I am being misunderstood or no one has an answer to my questions. I believe I was asking for it with the subject line of "Simple multi-level tie". What I should have wrote is "Wrapping hashes with arbitrary inflate/deflate methods." This is a tool that adds syntactic sugar to hashes. I developed it for the purpose of making complicated storage in hashes tied to DBM files nicer. It doesn't matter if you use CGI::query_string, Storable, join/split, pack/unpack, or even just use this to do some kind of wacky filtering, this tool isn't a marshalling tool, it is a syntax helper. What I want to know is, is Tie::HashWrapper a good name? If you don't like that name, what might you call it? HashWrapper sounds kind of dorky to me, but that's what first came to mind and I didn't want to spend all day trying to name it, I wanted to play code monkey. Cheers, Sterling -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] Microsoft is a cross between the Borg and the Ferengi. Unfortunately, they use Borg to do their marketing and Ferengi to do their programming. -- Simon Slavin
Re: Simple multi-level tie
On Wed, 2003-12-17 at 14:00, Andrew Sterling Hanenkamp wrote: > Therefore, I went in search of a solution to automate the > stringification. I didn't find anything other than MLDBM for doing > something like this and it seems like a little much for my purposes. All > I need ... As I understand it, the "standard" way to (de)marshall things anymore is to use Storable. see DirDB::Storable for an example of a multi-level tie that punts anything other than scalars and unblessed hashrefs to Storable for nstorage and retreival. If you're not going to have more than a thousand records (or you have reiserfs) DirDB might be the module for you rather than a single-file database. -- david nicol Where the hell did I put my coffee?
Re: Simple multi-level tie
Nice corollary, but this isn't really what Tie::HashWrapper addresses. Tie::HashWrapper is a general utility that could be used by you to clean up your code that was: tie %tied, 'MyDBM', ...; my $q = CGI->new($tied{key}); $q->param("x", "y"); $tied{key} = $q->query_string; to tie %wrappee, 'MyDBM', ...; tie %tied, 'Tie::HashWrapper', \%wrappee, -deflate_value => sub { shift->query_string }, -inflate_value => sub { CGI->new(shift)->Vars }; $tied{key}{x} = "y"; Regards, Sterling On Wed, 2003-12-17 at 14:12, Mark Stosberg wrote: > On Wed, Dec 17, 2003 at 02:00:23PM -0600, Andrew Sterling Hanenkamp wrote: > > > > Therefore, I went in search of a solution to automate the > > stringification. I didn't find anything other than MLDBM for doing > > something like this and it seems like a little much for my purposes. All > > I need is something like this: > > When I want to do this, I just use CGI.pm. With it, you can pass a hash > to the 'new' constructor, and use query_string() function (I think) to > get back a stringified version. > > Likewise, you can pass a query-string to the constructor, and get a hash > structure back. Keys with multiple values are supported, although I > usually don't have that case. > > Your solution may well be cleaner for general cases. > > Mark -- <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> <>< ><> Andrew Sterling Hanenkamp http://Andrew.Sterling.Hanenkamp.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] C makes it easy for you to shoot yourself in the foot. C++ makes that harder, but when you do, it blows away your whole leg. -- Bjarne Stroustrup
Re: Simple multi-level tie
On Wed, Dec 17, 2003 at 02:00:23PM -0600, Andrew Sterling Hanenkamp wrote: > > Therefore, I went in search of a solution to automate the > stringification. I didn't find anything other than MLDBM for doing > something like this and it seems like a little much for my purposes. All > I need is something like this: When I want to do this, I just use CGI.pm. With it, you can pass a hash to the 'new' constructor, and use query_string() function (I think) to get back a stringified version. Likewise, you can pass a query-string to the constructor, and get a hash structure back. Keys with multiple values are supported, although I usually don't have that case. Your solution may well be cleaner for general cases. Mark