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

Hello Monks! As usual I'm back with a bit of Moose related craziness that's threatening my limited sanity reserve. I'd like to see if some of you kind folks have some insight :)

So I have the following (code is cut down here). This is all from my SVN::Handle package. This package is mostly wrappers around SVN::Client methods and has a SVN::Client object it delegates to. Basic idea is to call $handle->commit with the log message and arguments, and it does the appropriate stuff to take care of setting the log callback correctly and all for you. The $self->client_obj returns the underlying SVN::Client object.

has 'log_message' => ( isa => 'Str', is => 'ro', writer => '_set_log_message', clearer => '_clear_log_message' ); sub commit { my ($self, $msg, @args) = @_; print STDERR "COMMIT CALLED WITH MSG ($msg)\n"; print STDERR "CURRENT MSG (".$self->log_message.")\n"; $self->set_log_message($msg) if defined $msg; my $new_msg = $self->log_message; print STDERR "NEW MSG (".$new_msg.")\n"; use Data::Dumper; print STDERR "DUMPED NEW MSG:".Dumper $new_msg; return $self->client_obj->commit(@args); } sub set_log_message { my ($self, $msg) = @_; $self->_set_log_message($msg); } sub log_message_callback { my $self = shift; my $log_msg = $self->log_message; use Data::Dumper; print STDERR "0 RETURNING (".$self->log_message.")\n"; print STDERR "1 RETURNING ($log_msg)\n"; print STDERR "LOG DUMP1:".Dumper $log_msg; print STDERR "LOG DUMP2:".Dumper $self; $_[0] = \$log_msg; $self->_clear_log_message; }

And the corresponding output (also stripped down to important bits):

COMMIT CALLED WITH MSG (Committing new plist file revisions.) CURRENT MSG () NEW MSG (Committing new plist file revisions.) DUMPED NEW MSG:$VAR1 = 'Committing new plist file revisions.'; 0 RETURNING (Committing new plist file revisions.) 1 RETURNING (*SVN::Handle::Committing new plist file revisions.) LOG DUMP1:$VAR1 = *{'SVN::Handle::Committing new plist file revisions. +'}; LOG DUMP2:$VAR1 = bless( { 'client_obj' => bless( { 'ctx' => bless( do{\(my $o = + 30042304)}, '_p_svn_client_ctx_t' ), 'auth_provider_callbacks' => + [ + \sub { "DUMMY" } + ], 'pool' => bless( do{\(my $o += bless( do{\(my $o = 187060184)}, '_p_apr_pool_t' ))}, 'SVN::Pool' ) +, 'log_msg_callback' => \sub { + "DUMMY" } }, 'SVN::Client' ), 'log_message' => 'Committing new plist file revisions +.', 'base_url' => 'https://subversion.jf.intel.com/iag/mg +d/prmd/mtd/tpt/Rapttr/', 'repo_name' => 'rapttr_svn' }, 'SVN::Handle::RapTTR' );

Apologies for the messy multi-line output (Is there a better way to format that?). The commit is failing with this error:

Invalid value in log_msg reference, must be undef or a string at /nfs/pdx/disks/nehalem.pde.077/perl/5.12.2/lib64/site_perl/x86_64-linux/SVN/Client.pm line 927.

This is clearly because of the problem shown by the debug output lines here:

my $log_msg = $self->log_message; print STDERR "0 RETURNING (".$self->log_message.")\n"; print STDERR "1 RETURNING ($log_msg)\n"; # and output 0 RETURNING (Committing new plist file revisions.) 1 RETURNING (*SVN::Handle::Committing new plist file revisions.)

What I can't figure out is what is being dumped from $log_msg there. It behaves as a string when printed directly through the $self->log_message accessor. However, when I assign the return of that accessor to $log_msg, then print $log_msg I get that stringified...typeglob? The output from the dumped $self object clearly shows the log_message field having the correct value assigned to it, so this seems to be a case of a problem with the Moose accessor somehow.

I can't seem to get this to occur with a focused test case, so it must be related to other code somehow. But I follow up setting the log message with the commit directly, and the log_message value is dumped with the correct string value immediately prior to the commit. It's only inside the log_message_callback method where the problem shows up...which is called from the SVN::Client internals.

Any insights for me on this one? In any case, if you made it this far I genuinely appreciate your time :)

UPDATE: I've found the code works fine as long as I remove this:

$self->_clear_log_message;

from the log_message_callback method. Even with that line, it works the first time until that clear occurs. Am I improperly declaring/using the clearer method?

Replies are listed 'Best First'.
Re: Moose accessor odd return
by ikegami (Patriarch) on Jan 05, 2012 at 20:22 UTC

    That you didn't provide runnable code that demonstrates the problem limits our options. I'd like to see

    use Devel::Peek; Dump($self->log_message); Dump($log_msg);

    What's Perl version is this?

      Thanks for your time as always Ikegami. I tried to get a small piece of runnable code that demonstrated the issue to no avail. Thus I instead tried to give the pieces of code of interest. My apologies for no running code. This is perl 5.12.2

      At this point I've gone ahead and removed the clear line as I mentioned in my update. Thus far it seems to be working well, but I'm keeping an eye on it. I'm totally swamped but at some point I'll see if I can dig the problem code out of my repository, reproduce the issue, and give you the output you request.