-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[String] add LazyString to provide memoizing stringable objects #34298
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
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
04a8350
to
6bffaf5
Compare
@symfony/mergers PR is ready. I updated the description to better explain what this does. |
6bffaf5
to
ff02a31
Compare
2670fac
to
3fa9d12
Compare
lyrixx
reviewed
Jan 24, 2020
stof
reviewed
Jan 24, 2020
3fa9d12
to
c3e04bd
Compare
lyrixx
approved these changes
Jan 24, 2020
c3e04bd
to
c7eb8d1
Compare
chalasr
approved these changes
Jan 27, 2020
fabpot
approved these changes
Feb 3, 2020
c7eb8d1
to
4bb19c6
Compare
Thank you @nicolas-grekas. |
fabpot
added a commit
that referenced
this pull request
Feb 3, 2020
…e objects (nicolas-grekas) This PR was merged into the 5.1-dev branch. Discussion ---------- [String] add LazyString to provide memoizing stringable objects | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Replaces #34190 The proposed `LazyString` class is a value object that can be used in type declarations of our libraries/apps. Right now, when a method accepts or returns "strings|stringable-objects", the most accurate type declaration one can use is `string|object` (either in docblocks or in union types in PHP 8). The goal of `LazyString` is to allow one to use `string|LazyString` instead and gain type-accuracy, thus type-safety while doing so. Another defining property of the proposed class is also that it memoizes the computed string value so that the computation happens only once. Two factories are provided to create a `LazyString` instance: - `LazyString::fromStringable($value): self` -> turns any object with `__toString()` into a `LazyString` - `LazyString::fromCallable($callback, ...$arguments): self` -> delegates the computation of the string value to a callback (optionally calling it with arguments). Two generic helpers are also provided to help deal with stringables: - `LazyString::isStringable($value): bool` -> checks whether a value can be safely cast to string, considering `__toString()` too. This replaces the boilerplate we all have to write currently (`is_string($value) || is_scalar($value) || is_callable([$value, '__toString'])`) - `LazyString::resolve($value): string` -> casts a stringable value into a string. This is similar to the casting `(string)` operator or to `strval()`, but it throws a `TypeError` instead of a PHP notice when a non stringable is passed. This helps e.g. with code that enabled strict types and want to maintain compatibility with stringable objects. An additional feature of `LazyString` instances is that they allow exceptions thrown from the wrapped `__toString()` methods or callbacks to be propagated. This requires having the `ErrorHandler` class from the `Debug` or `ErrorHandler` components registered as a PHP error handler (already the case for any Symfony apps by default). As a reminder, throwing from `__toString()` is not possible natively before PHP 7.4. Commits ------- 4bb19c6 [String] add LazyString to provide generic stringable objects
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Replaces #34190
The proposed
LazyString
class is a value object that can be used in type declarations of our libraries/apps.Right now, when a method accepts or returns "strings|stringable-objects", the most accurate type declaration one can use is
string|object
(either in docblocks or in union types in PHP 8). The goal ofLazyString
is to allow one to usestring|LazyString
instead and gain type-accuracy, thus type-safety while doing so.Another defining property of the proposed class is also that it memoizes the computed string value so that the computation happens only once.
Two factories are provided to create a
LazyString
instance:LazyString::fromStringable($value): self
-> turns any object with__toString()
into aLazyString
LazyString::fromCallable($callback, ...$arguments): self
-> delegates the computation of the string value to a callback (optionally calling it with arguments).Two generic helpers are also provided to help deal with stringables:
LazyString::isStringable($value): bool
-> checks whether a value can be safely cast to string, considering__toString()
too. This replaces the boilerplate we all have to write currently (is_string($value) || is_scalar($value) || is_callable([$value, '__toString'])
)LazyString::resolve($value): string
-> casts a stringable value into a string. This is similar to the casting(string)
operator or tostrval()
, but it throws aTypeError
instead of a PHP notice when a non stringable is passed. This helps e.g. with code that enabled strict types and want to maintain compatibility with stringable objects.An additional feature of
LazyString
instances is that they allow exceptions thrown from the wrapped__toString()
methods or callbacks to be propagated. This requires having theErrorHandler
class from theDebug
orErrorHandler
components registered as a PHP error handler (already the case for any Symfony apps by default). As a reminder, throwing from__toString()
is not possible natively before PHP 7.4.