As noted in the "Future Scope" section of the property hooks RFC, reusable package hooks are not part of the first RFC, but the authors @iluuu1994 and @Crell envision it being added later. Here are some ideas of how it could be implemented.
Swift
The concept here is called property wrappers. Here's an example from their documentation:
@propertyWrapper
struct TwelveOrLess {
private var number = 0
var wrappedValue: Int {
get { return number }
set { number = min(newValue, 12) }
}
}
struct SmallRectangle {
@TwelveOrLess var height: Int
@TwelveOrLess var width: Int
}
rectangle.height = 10 // Width is set to 10
rectangle.height = 24 // Width is set to 12
See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/#Property-Wrappers
Kotlin
The concept here is called property delegates. Here's an example of how these are implemented:
// Syntax
var name: String by NameDelegate()
// Compiled to
val name$delegate = NameDelegate()
var name: String
get() = name$delegate.getValue(this, this::name)
set(value) { name$delegate.setValue(this, this::name, value) }
See https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531
Idea for PHP
Going down the same path as Kotlin (which the PHP RFC is inspired quite a bit from) but without introducing any new keywords, we could come up with the following:
class Environment {
// Syntax with "as" (doesn't conflict with syntax highlighting like "use" would)
public string $home as new ByLazy(fn() => getenv('HOME'));
// Compiled to the following which already works with PR #166 merged
private $__home_delegate= new ByLazy(fn() => getenv('HOME'));
public string $home {
get => $this->__home_delegate->get($this, (object)['value' => &$field]);
set => $this->__home_delegate->set($this, (object)['value' => &$field], $value);
}
}
The ByLazy implementation is as follows:
class ByLazy {
public function __construct(private callable $init) { }
public function get($self, $property) {
return ($property->value??= [($this->init)()])[0];
}
public function set($self, $property, $value) {
$property->value= [$value];
}
}
Note: Using an array for a value will allow initializing the property to NULL.
See also
As noted in the "Future Scope" section of the property hooks RFC, reusable package hooks are not part of the first RFC, but the authors @iluuu1994 and @Crell envision it being added later. Here are some ideas of how it could be implemented.
Swift
The concept here is called property wrappers. Here's an example from their documentation:
See https://docs.swift.org/swift-book/documentation/the-swift-programming-language/properties/#Property-Wrappers
Kotlin
The concept here is called property delegates. Here's an example of how these are implemented:
See https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531
Idea for PHP
Going down the same path as Kotlin (which the PHP RFC is inspired quite a bit from) but without introducing any new keywords, we could come up with the following:
The
ByLazyimplementation is as follows:Note: Using an array for a value will allow initializing the property to NULL.
See also