package File::Attributes::Recursive; use warnings; use strict; our $VERSION = '0.02'; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(get_attribute_recursively get_attributes_recursively list_attributes_recursively); our %EXPORT_TAGS = (all => \@EXPORT_OK); use File::Attributes qw(get_attribute list_attributes); use Path::Class; use Cwd qw(abs_path); use Carp; sub get_attribute_recursively { my $file = shift; my $top = shift; my $attribute = shift; if(!defined $attribute){ $attribute = $top; $top = '/'; } $file = file($file)->absolute; $top = dir($top)->absolute; if(!$top->subsumes($file)){ croak "get_attribute_recursively: filename ($file) must ". "contain top ($top)"; } my $result; while($top->subsumes($file)){ eval { $result = get_attribute($file, $attribute); }; last if defined $result; $file = $file->parent; } return $result; } sub get_attributes_recursively { my $file = shift; my $top = shift; $top = '/' if !defined $top; $file = file($file)->absolute; $top = dir($top)->absolute; if(!$top->subsumes($file)){ croak "get_attributes_recursively: filename ($file) must ". "contain top ($top)"; } my %result; while($top->subsumes($file)){ my @attributes = list_attributes($file); foreach my $attribute (@attributes){ next if exists $result{$attribute}; eval { $result{$attribute} = get_attribute($file, $attribute); }; } $file = $file->parent; } return %result; } sub list_attributes_recursively { my $file = shift; my $top = shift; $top = '/' if !defined $top; $file = file($file)->absolute; $top = dir($top)->absolute; if(!$top->subsumes($file)){ croak "get_attributes_recursively: filename ($file) must ". "contain top ($top)"; } my %results; while($top->subsumes($file)){ eval { my @subresults = list_attributes($file); @results{@subresults} = @subresults; }; $file = $file->parent; } return keys %results; } __END__ =head1 NAME File::Attributes::Recursive - Inherit file attributes from parent directories. =head1 VERSION Version 0.02 =head1 SYNOPSIS Works like C, but will recurse up the directory tree until a matching attribute is found. =head1 EXPORT None, by default. Specify the functions you'd like to use as arguments to the module. C<:all> means export everything. =head1 FUNCTIONS =head2 get_attribute_recursively($file, [$top], $attribute) Returns the value of attribute C<$attribute>. If C<$top> is specified, then the search will terminate when the path no longer contains C<$top>. (i.e. if C<$file> is C and C<$top> is =head2 get_attributes_recursively($file, [$top]) Returns a hash of key value pairs for all attributes that apply to C<$file>. Only the closest attributes are returned. Given: /a (a = yes, foo = bar) /a/b (b = yes, foo = baz) /a/b/c (c = yes) C will return: (a => yes, b => yes, c => yes, foo => baz). The C<< foo => bar >> is masked by the "closer" C<< foo => baz >>. =head2 list_attributes_recursively($file, [$top]) Returns a list of attributes that are defined and apply to C<$file>. Like C, but faster. =head1 NOTABLY ABSENT FUNCTIONS =head2 unset_attribute_recursively There are two possible ways for this function to behave -- either recurse until the attribute is removed, or recurse to C, removing the attribute at each level. The first doesn't make sense, and the second is dangerous. If you need this function, write it for the specific needs of your application; I think that's the safest thing to do. (Note that C refuses to C, so I think there's some precedent here.) =head1 AUTHOR Jonathan Rockway, C<< >> =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc File::Attributes::Recursive You can also look for information at: =over 4 =item * AnnoCPAN: Annotated CPAN documentation L =item * CPAN Ratings L =item * RT: CPAN's request tracker L =item * Search CPAN L =back =head1 ACKNOWLEDGEMENTS =head1 COPYRIGHT & LICENSE Copyright 2006 Jonathan Rockway, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; # End of File::Attributes::Recursive