Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data::Dumper incomplete reference relationship #22888

Open
damluk opened this issue Jan 5, 2025 · 5 comments
Open

Data::Dumper incomplete reference relationship #22888

damluk opened this issue Jan 5, 2025 · 5 comments
Labels
Closable? We might be able to close this ticket, but we need to check with the reporter dist-Data-Dumper issues in the dual-life blead-first Data-Dumper distribution

Comments

@damluk
Copy link

damluk commented Jan 5, 2025

Perl: 5.36
Module: Data::Dumper

The following Dump output correctly shows the relationship between $foo and $bar:

root@fa394195f07f:~# cat good.pl 
use Data::Dumper;
my $foo = [42];
my $bar = [\$foo];
CORE::say Data::Dumper->new([$foo, $bar], [qw[foo bar]])->Indent(0)->Dump;
root@fa394195f07f:~# perl good.pl 
$foo = [42];$bar = [\$foo];

However, when $foo is not a reference, the relationship is lost:

root@fa394195f07f:~# cat bad.pl 
use Data::Dumper;
my $foo = 42;
my $bar = [\$foo];
CORE::say Data::Dumper->new([$foo, $bar], [qw[foo bar]])->Indent(0)->Dump;
root@fa394195f07f:~# perl bad.pl 
$foo = 42;$bar = [\42];
@damluk
Copy link
Author

damluk commented Jan 6, 2025

root@fa394195f07f:~# cat workaround.pl 
package Dumper {
  use parent 'Data::Dumper';
  sub new {
    my ($class, $names) = (shift, pop);
    $class->SUPER::new(\@_, $names);
  }
}
my $foo = 42;
my $bar = [\$foo];
CORE::say Dumper->new($foo, $bar, [qw[foo bar]])->Indent(0)->Dump;
root@fa394195f07f:~# perl workaround.pl 
$foo = 42;$bar = [\$foo];

@tonycoz
Copy link
Contributor

tonycoz commented Jan 6, 2025

The problem is the entries in the first array ref are copies of $foo and $bar, so that step loses the link between them.

D::D handles this reasonably for references, but 42 in the array ref is no different to any other 42, consider if it were 0 or 1 instead.

For the class case, @_ contains aliases to $foo and $bar so that link remains.

You can also handle this with an anonymous sub:

my @names = qw(foo bar);
CORE::say sub { Data::Dumper->new(\@_, \@names)->Indent(0)->Dump; }->($foo, $bar);

@jkeenan jkeenan added dist-Data-Dumper issues in the dual-life blead-first Data-Dumper distribution and removed Needs Triage labels Jan 6, 2025
@jkeenan
Copy link
Contributor

jkeenan commented Jan 6, 2025

@tonycoz, is there any need for clarification of documentation here? (Otherwise, it seems this ticket is closable.)

@jkeenan jkeenan added the Closable? We might be able to close this ticket, but we need to check with the reporter label Jan 6, 2025
@tonycoz
Copy link
Contributor

tonycoz commented Jan 7, 2025

@tonycoz, is there any need for clarification of documentation here? (Otherwise, it seems this ticket is closable.)

I'm not sure.

The "working" case may be an accident, unlike new() the Values() method makes no attempt to save the aliasing of the values, copying them instead:

my @names = qw(foo bar);
CORE::say sub { Data::Dumper->new([], \@names)->Values(\@_)->Indent(0)->Dump; }->($foo, $bar);
# $foo = 42;$bar = [\42];

I think the Seen() method is the blessed way to get what the OP is after here, but it looks broken.

I tried supplying Seen({ '\\$foo' => \$foo, '\\$bar' => \$bar }) which sort of matches the result of Seen() on the "working" case, but Seen() mangles it, adding extra $.

So there may be a real bug here.

@damluk
Copy link
Author

damluk commented Jan 7, 2025

The variables to be dumped are not always known at compile time. If ($values, $names) = [$foo, $bar], [qw[foo bar]]) is only known at run time, one cannot use the alias trick unless the Data::Dumper call is evaled with an expanded list of variables. It would be better to have a mode of operation that can handle this case without eval. For example, the current call

Data::Dumper->new([$foo, $bar], [qw[foo bar]])

could be the implicit mode that is equivalent to this explicit one,

Data::Dumper->new([$foo, $bar], [qw[foo bar]], deref => 0)

while the following mode would have the opportunity to give correct results for the bad.pl use case:

Data::Dumper->new([\$foo, \$bar], [qw[foo bar]], deref => 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closable? We might be able to close this ticket, but we need to check with the reporter dist-Data-Dumper issues in the dual-life blead-first Data-Dumper distribution
Projects
None yet
Development

No branches or pull requests

3 participants