-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Do not wrap return result to PSObject
when converting ScriptBlock to delegate
#10619
Conversation
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.
This could be a nightmare to track down if it breaks any real world code. It's not the sort of thing that is easy to search for.
It's fine to reject this PR if we consider it too risky. |
Can a (enhanced) telemetry help to discover where (projects) and how it is used? |
The only case I can think of that will be affected is that the target delegate type has the return type |
Looking the code PowerShell/src/System.Management.Automation/engine/lang/scriptblock.cs Lines 777 to 789 in 6965ba7
What does the code return still unwrapped object or already PSObject? (I mean PSConvertBinder) |
@iSazonov Can you please rephrase your question? I'm not sure I understand it. |
The code I referenced calls a code you modified in the PR. I guess that |
|
@daxian-dbw Is this ready? |
No, this is not ready. I don't think this should be in rc.1. Nobody really reviews it and it might be rejected by the committee. |
I think it is right direction. Delegates look good for future optimizations and this cleanup once can simplify our lives. |
@PowerShell/powershell-committee reviewed this PR and believes the possible breaking case described in #10619 (comment) is unlikely and it falls into the |
object resultArray = result.ToArray(); | ||
return wrapToPSObject ? LanguagePrimitives.AsPSObjectOrNull(resultArray) : resultArray; |
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.
Is the converting to immutable array mandatory?
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.
@iSazonov Sorry for the super long delay to respond to your comment.
The result.ToArray()
is existing code, and it would be a breaking change to end users to change that because users may expect an object array as it's always be.
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.
If the PR breaks an C# application in any case and developers have to fix their code we could weight removing result.ToArray()
too. If we think about enumeration the replacing List<object> with Array does seem not break this. We could add test for the default
case.
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.
@daxian-dbw Could you please share your thoughts about my last comment?
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.
Note that this method is also used by DoInvokeReturnAsIs
. The current change keeps the existing behavior of that API, but removing result.ToArray()
definitely breaks it.
Also, there is no obvious benefit by removing result.ToArray()
except for a bit less allocation that may not be noticeable, so I don't think a breaking change can be justified.
@iSazonov I just reviewed this PR and think it's ready for official review. Can you please take a look when you have time? Thanks! |
@SeeminglyScience Perhaps you are interesting to review the PR. |
@rjmholt please also review this PR. Thanks! |
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.
LGTM
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.
This seems reasonable. I take the point about real world code depending on this, but it's also something that makes more sense this way and is probably not very widely used, so seems less dangerous than we might think
@iSazonov I think this is ready to merge. Thanks! |
Should we have a doc issue? |
Good point. I don't think we have a doc about the |
🎉 Handy links: |
PR Summary
Avoid wrapping return result to
PSObject
when converting ScriptBlock to delegate.When a
ScriptBlock
is converted to a delegate type, it's supposed to be used in C# context, and wrapping the result toPSObject
brings unneeded troubles:PSObject
essentially gets unwrapped, so we basically createsPSObject
in vain.object
, thePSObject
is returned, making it hard to work with the true return value in C# code.This is a breaking change for the delegate types with the
object
return type:PSObject
instance.PSObject
if that's what the script actually returns.But I think this would fall in the
Bucket 3 Grey Area
.With this change, when setting
AddToHistoryHandler
to{ param($line) $line -notmatch '^\s+|ToSecureString|AsPlainText' }
, the time to load history entries from the history file reduces about100
ms on my dev machine (from~1750
to~1650
) for213226
history records in the file.PR Context
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.