http://qs1969.pair.com?node_id=328610

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

How do I communicate @HOGS from &view_handler to find_hidden_views_with_resortable_indexes( $db ) without having to use a global? I'm certain there is a normal XML::Twig facility or an idiomatic way to do this. Am I expected to pass in closures to XML::Twig->new? I think it'd be nice to share the same parser across the program instead of having to recreate it during the loop.

Updates Fixed a bug where @hogs was returned but @HOGS was tested. Also replaced @HOGS = () with local @HOGS.

use strict; use warnings; use vars qw(@HOGS $TWIG $DEFAULT_SERVER); use Notes::OLE (); use File::Basename (); use File::Temp (); use XML::Twig; use YAML (); $DEFAULT_SERVER = 'dev1'; exit main( @ARGV ); =pod <database> <view name='(...)'> <column resort='...'/> </view> </database> INTO server: filepath: view name: WHERE view name starts with ( and ends with ) and has a column with a resort attribute. =cut sub main { my $server = shift(@_) || $DEFAULT_SERVER; $TWIG = XML::Twig->new( twig_handlers => { q[view[@name =~ /^\(.+?\)$/]] => \&handle_view }, twig_roots => { view => 1, column => 1 } ); my %hogs; for my $dbp ( Notes::OLE::server_databases( $server ) ) { my $db = $Notes::OLE::S->GetDatabase( $dbp->{'server'}, $dbp->{'filepath'} ) or next; my @hogs = find_hidden_views_with_resortable_indexes( $db ); if ( @hogs ) { $hogs{ $dbp->{'server'} }{ $dbp->{'filepath'} } = [ @hogs ]; } } my $output = File::Basename::basename( $0 ); $output =~ s/\.[^.]+$/.yml/; YAML::DumpFile( $output, \%hogs ); my $editor = $ENV{'EDITOR'} || 'notepad'; system( $editor, $output ); return 1; } sub find_hidden_views_with_resortable_indexes { my $db = shift; # Input my $notes = $db->CreateNoteCollection( 0 ); $notes->{'SelectViews'} = 1; $notes->BuildCollection; # Output my $temp_file = File::Temp::tmpnam(); my $stream = $Notes::OLE::S->CreateStream; $stream->Open( $temp_file ); # Exporter my $exporter = $Notes::OLE::S->CreateDXLExporter( $notes, $stream +); $exporter->Process; # Cleanup so there are no open handles to the file $stream->Close; # Run XML::Twig on the exported schema local @HOGS; $TWIG->parsefile( $temp_file ); $TWIG->purge; # Remove the exported schema unlink $temp_file or warn "Couldn't delete $temp_file: $!"; return @HOGS; } sub handle_view { my ($t, $view) = @_; my $name = $view->att( 'name' ); push @HOGS, $name if $view->children( 'column[@resort]' ); return 1; }

janitored by ybiC: Balanced <readmore> tags around the codeblock, to reduce vertical scrolling on Monastery front page