Skip to content

Instantly share code, notes, and snippets.

@fesor
Created June 27, 2016 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fesor/09c91090cef3da0da0e143cca3ae2d62 to your computer and use it in GitHub Desktop.
Save fesor/09c91090cef3da0da0e143cca3ae2d62 to your computer and use it in GitHub Desktop.
scopes
<?php
namespace Fesor\Caffeine;
final class Scope
{
private $payload;
private $parent;
/**
* Scope constructor.
* @param Scope $parent
*/
private function __construct(Scope $parent = null)
{
$this->parent = $parent;
$this->payload = [];
}
public static function create()
{
return new self();
}
public static function withPayload(array $payload)
{
$scope = new self();
$scope->payload = $payload;
return $scope;
}
public function __get($name)
{
$scope = $this;
while($scope) {
if (array_key_exists($name, $scope->payload)) {
return $scope->payload[$name];
}
$scope = $scope->parent;
}
return null;
}
public function __set($name, $value)
{
$this->payload[$name] = $value;
}
function __isset($name)
{
$scope = $this;
while($scope) {
if (array_key_exists($name, $scope->payload)) {
return true;
}
$scope = $scope->parent;
}
return false;
}
public function __call($name, $arguments)
{
$callable = $this->__get($name);
if (is_callable($callable)) {
return call_user_func_array($callable, $arguments);
}
throw new \BadMethodCallException(sprintf('Method "%s" not found in current scope neither it parents'));
}
public function inherit()
{
return new self($this);
}
public function bind(\Closure $callable)
{
\Closure::bind($callable, $this, $this);
}
}
<?php
$rootScope = new Scope();
$rootScope->val = 'default';
$scope1 = $rootScope->inherit();
$scope1->val = 'scope 1 val';
$childScope = $scope1->inherit();
$childScope->val = 'child scope val'
$scope2 = $rootScope->inherit();
$scope2->val = 'scope 2 val';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment