-
Notifications
You must be signed in to change notification settings - Fork 594
Improvements to B::Deparse handling of signatured subs #23710
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
base: blead
Are you sure you want to change the base?
Conversation
I really appreciate the (best) effort put into this. I only use
I don't think this kind of usage will trigger the behaviour described with regard to "ambient pragmas", though. |
Indeed so. In the usual
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are you planning to merge this?
- Branch as is?
- Squashing some commits and fast-forward merge (i.e. no merge commit)
- With a merge commit?
My personal view: there are definitely some commits that I would keep separate (i.e. the tidying up) .
warning_bits => $warning_bits, | ||
'%^H' => $hinthash, | ||
); | ||
$deparse->ambient_pragmas_from_caller; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit tests for ->ambient_pragmas_from_caller
This commit is slightly confusing; that it: when seeing the commit title I would've expected tests for the ambient_pragmas_from_caller
function but what it is doing is using it inside the tests.
(If that is all that was intended then fine; I'm not asking for explicit tests for the ambient_pragmas_from_caller
it's just what I expected to see in the commit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah that was more of a note to myself to remind me. I'll just squash it in to the previous commit.
lib/B/Deparse.pm
Outdated
foreach my $parami ( 0 .. $#param_padix ) { | ||
my $argix = $parami; | ||
|
||
$code .= "my $param_padname[$parami] = "; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Best-effort deparse of OP_MULTIPARAM when feature 'signatures' is disabled
Reading up a bit on signatures, in perlsub, it contains:
An optional parameter can be nameless just like a mandatory parameter. For example,
sub foo ($thing, $ = 1) { print $thing; }
The parameter's default value will still be evaluated if the corresponding argument isn't supplied, even though the value won't be stored anywhere. This is in case evaluating it has important side effects. However, it will be evaluated in void context, ...
It's not yet clear to me how/if this is handled.
(But I'm not that familiar yet with this code and/or signatures so I might be overlooking something)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not yet clear to me how/if this is handled.
Ooh, good catch. I don't have a test for that yet, and in fact I'm not sure the code will even handle it. Looks like more work to do there.
lib/B/Deparse.pm
Outdated
as possible. This is performed on a B<best-effort> basis. It is not | ||
guaranteed to perfectly capture the semantics of the signature's behaviour, | ||
only to offer a human-readable suggestion as to what it might do. | ||
Furthermore. it is not guaranteed to be able to reproduce every possible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Add docs to B::Deparse about signatures pure-perl fallback
Furthermore.
--> Furthermore,
?
Yeah I'll squash some of them out and preserve the identity of others. I'll have a hack at that now. |
Add C<...> wrapping around the name of the module, also a few other places. Also add L<...> wrapping around names of other modules.
…res feature enabled
Rebased, squashed some commits, fixed a few more little docs issues, added code + tests for anonymous signature params. PTAL. |
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Unit tests for B::Deparse coderef2text on signatured sub with signatures feature enabled
Slightly wondering: should $deparse->ambient_pragmas_from_caller;
be called after the test(s) to reset the state?
In the earlier block of code (line 96) it does happen explicitely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably no huge need to reset it after some tests, as any newly-added test block that gets added after this may want to set it back to something else for its own purposes anyway.
else { | ||
# anonymous params without defaulting expressions can be entirely ignored | ||
$param_padix[$parami] or next; | ||
|
||
$stmt .= "\$_[$argix]"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Best-effort deparse of OP_MULTIPARAM when feature 'signatures' is disabled
While the code works it was a bit confusing at first.
I would probably write this as:
if (my $defmode = $param_defmode[$parami]) {
...
}
elsif (not $param_padix[$parami]) {
# anonymous params without defaulting expressions can be entirely ignored
next;
}
else {
$stmt .= "\$_[$argix]";
}
The check is also inconsistent with the earlier check. Earlier check (on line 1130):
if( length $param_padname[$parami] > 1 ) {
while here it just checks for a true value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the code works it was a bit confusing at first. I would probably write this as:
...
I wanted to structure it in two branches, for optional vs. mandatory params, and within each branch then have a condition for anonymous versions of those. It's two binary choices, not a threeway split.
The check is also inconsistent with the earlier check. Earlier check (on line 1130):
...
while here it just checks for a true value.
Ohyes, hmm. That's quite subtle.
Anonymous mandatory params don't even get allocate a pad slot, so their padname is undefined. Anonymous optional params need a pad slot to detect if it's been set or not, and therefore have a name that is simply '$'. So the conditions for detecting named vs. anonymous params are different depending if they're optional or mandatory.
I have explained further in some more comment.
foreach my $parami ( 0 .. $#param_padix ) { | ||
my $argix = $parami; | ||
|
||
my $stmt = "my $param_padname[$parami] = "; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Best-effort deparse of OP_MULTIPARAM when feature 'signatures' is disabled
Can $param_padname[$parami]
be undef? (If so then it will trigger a warning)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the name is always at least '$'
lib/B/Deparse.pm
Outdated
|
||
# anonymous params with defaults don't create or assign a variable but | ||
# still evaluate the defaulting expression for side-effects | ||
if( length $param_padname[$parami] > 1 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit Best-effort deparse of OP_MULTIPARAM when feature 'signatures' is disabled
nit-picking: style seems appears inconsistent?
Earlier if-blocks are all if (...) {
while this is if( ... ) {
(if/when intentional then feel free to ignore)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahyes, fixed.
->ambient_pragmas_from_caller
method for simplicityOP_MULTIPARAM
to prior pure-perl behavioursCurrently no perldelta, but I could be convinced to add one if considered significant. Do we normally include changes to bundled modules in perldelta?