Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Tie::File::AsHash(3)  User Contributed Perl Documentation Tie::File::AsHash(3)

       Tie::File::AsHash - Like	Tie::File but access lines using a hash
       instead of an array

	use Tie::File::AsHash;

	tie my %hash, 'Tie::File::AsHash', 'filename', split =>	':'
	       or die "Problem tying %hash: $!";

	print $hash{foo};		   # access hash value via key name
	$hash{foo} = "bar";		   # assign new	value
	my @keys = keys	%hash;		   # get the keys
	my @values = values %hash;	   # ... and values
	exists $hash{perl};		   # check for existence
	delete $hash{baz};		   # delete line from file
	$hash{newkey} =	"perl";		   # entered at	end of file
	while (($key,$val) = each %hash)   # iterate through hash
	%hash =	();			   # empty file

	untie %hash;			   # all done

       Here is sample text that	would work with	the above code when contained
       in a file:


       "Tie::File::AsHash" uses	"Tie::File" and	perl code so files can be tied
       to hashes.  "Tie::File" does all	the hard work while
       "Tie::File::AsHash" works a little magic	of its own.

       The module was initially	written	for managing htpasswd-format password

	use Tie::File::AsHash;
	tie %hash, 'Tie::File::AsHash',	'filename', split => ':'
	       or die "Problem tying %hash: $!";

	(use %hash like	a regular ol' hash)

	untie %hash;  #	changes	saved to disk

       Easy enough eh?

       New key/value pairs are appended	to the end of the file,	"delete"
       removes lines from the file, "keys" and "each" work as expected,	and so

       "Tie::File::AsHash" will	not die	or exit	if there is a problem tying a
       file, so	make sure to check the return value and	check $! as the
       examples	do.

       The only	argument "Tie::File::AsHash" requires is the "split" option,
       besides a filename.  The	split option's value is	the delimiter that
       exists in the file between the key and value portions of	the line.  It
       may be a	regular	expression, and	if so, the "join" option must be used
       to tell "Tie::File::AsHash" what	to stick between the key and value
       when writing to the file.  Otherwise, the module	dies with an error

	tie %hash, 'Tie::File::AsHash',	'filename',  split => qr(\s+), join => " "
	       or die "Problem tying %hash: $!";

       Obviously no one	wants lines like "key(?-xism:\s+)val" in their files.

       All other options are passed directly to	"Tie::File", so	read its
       documentation for more information.

       When "keys", "values", or "each"	is used	on the hash, the values	are
       returned	in the same order as the data exists in	the file, from top to
       bottom, though this behavior should not be relied on and	is subject to
       change at any time (but probably	never will).

       "Tie::File::AsHash" doesn't force keys to be unique.  If	there are
       multiple	keys, the first	key in the file, starting at the top, is used.
       However,	when "keys", "values", or "each" is used on the	hash, every
       key/value combination is	returned, including duplicates,	triplicates,

       Keys can't contain the split character.	Look at	the perl code that
       "Tie::File::AsHash" is comprised	of to see why (look at the regexes).
       Using a regex for the split value may be	one way	around this issue.

       "Tie::File::AsHash" hasn't been optimized much.	Maybe it doesn't need
       to be.  Optimization could add overhead.	 Maybe there can be options to
       turn on and off various types of	optimization?

       "" changes password	file entries when the lines are	of
       "user:encryptedpass" format.  It	can also add users.

	#!/usr/bin/perl	-w

	use strict;
	use Tie::File::AsHash;

	die "Usage: $0 user password" unless @ARGV == 2;
	my ($user, $newpass) = @ARGV;

	tie my %users, 'Tie::File::AsHash', '/pwdb/users.txt', split =>	':'
	    or die "Problem tying %hash: $!";

	# username isn't in the	password file? see if the admin	wants it added
	unless (exists $users{$user}) {

		print "User '$user' not	found in db.  Add as a new user? (y/n)\n";
		chomp(my $y_or_n = <STDIN>);
		set_pw($user, $newpass)	if $y_or_n =~ /^[yY]/;

	} else {

		set_pw($user, $newpass);
		print "Done.\n";


	sub set_pw { $users{$_[0]} = crypt($_[1], "AA")	}

   Using the join option
       Here's code that	would allow the	delimiter to be	':' or '#' but prefers

	tie my %hash, 'Tie::File::AsHash', 'filename', split =>	qr/[:#]/, join => "#" or die $!;

       Say you want to be sure no ':' delimiters exist in the file:

	while (my ($key, $val) = each %hash) {

	       $hash{$key} = $val;


       Chris Angell <>

       Feel free to email me with suggestions, fixes, etc.

       Thanks to Mark Jason Dominus for	authoring the superb Tie::File module.

       Copyright (C) 2004, Chris Angell.  All Rights Reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself, including any version of Perl 5.

       perl(1),	perltie(1), Tie::File(1)

perl v5.32.0			  2006-04-07		  Tie::File::AsHash(3)


Want to link to this manual page? Use this URL:

home | help