http://www.perlmonks.org?node_id=664900

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

Wise Monks: I'm using XML::Twig and its function handlers. These take coderefs, to which are passed (as @_) the values of the twig and the section being processed. However, if I want to pass the coderef other values as well, it doesn't seem to retrieve the twig and section as I'd expect. I'm a bit stumped, I can't seem to find this case in the documentation. Example:
#!/usr/bin/perl use XML::Twig; my $t=XML::Twig->new( twig_handlers => { name => \&my_s }); $t->parse('<doc><name>Alice</name><name>Bob</name></doc>'); sub my_s { my ($twig, $section, $greeting) = @_; print $greeting || "Hello" , ", ", $section->text(), "!\n"; } # Yields: # Hello, Alice! # Hello, Bob!
If I try
my $t=XML::Twig->new( twig_handlers => { name => \&my_s("Hi") }); # Can't call method "text" on an undefined value # likewise with &my_s->("Hi")
What am I missing?

Replies are listed 'Best First'.
Re: Passing additional arguments to XML::Twig handlers
by Fletch (Bishop) on Jan 29, 2008 at 14:31 UTC

    Use an anonymous coderef (which adds the extra arguments) to set the handler.

    my $t = XML::Twig->new( twig_handlers => { name => sub { my_s( @_, "Hi +" ) } } );

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Thanks! This seems to work fine.
Re: Passing additional arguments to XML::Twig handlers
by mirod (Canon) on Jan 29, 2008 at 14:43 UTC

    The best explanation I have seen about closures and how to use them in XML::Twig is Simon Cozens' Achieving Closure.

Re: Passing additional arguments to XML::Twig handlers
by moritz (Cardinal) on Jan 29, 2008 at 14:33 UTC
    If you want only constant args, you can fall back on closures:
    my $greeting = "hi"; my $my_s = sub { my ($twig, $section) = @_; print $greeting || "Hello" , ", ", $section->text(), "!\n"; }

    You can then pass the closure in $my_s just like a normal reference to a sub.

      The args change from parse to parse, unfortunately. Closures are something I need to get more used to in general, though - thanks!