Skip to content

Instantly share code, notes, and snippets.

@jaggy
Last active January 14, 2020 19:57
Show Gist options
  • Save jaggy/b23bb6ad5801b17ee44838ce41af8010 to your computer and use it in GitHub Desktop.
Save jaggy/b23bb6ad5801b17ee44838ce41af8010 to your computer and use it in GitHub Desktop.
An exercise of implementing a higher order if.

Higher Order If

Because of short closures, I ended up wondering if Higher Order Ifs are nice to read.

I don't really recommend this, it's just a fun exercise to help me figure out how Laravel did the Higher Order stuff. 😅

public static function boot()
{
    static::created(function ($user) {
       if ($user->isSuperAdmin()) {
            $task->activate();
        }
    });
}

to

# Using the "Iffable"
public static function boot()
{
    static::created(fn ($user) => $user->if->isSuperAdmin()->activate());
}

# or
public static function boot()
{
    static::created(fn ($user) => $user->if()->isSuperAdmin()->activate());
}
<?php
namespace App;
use Illuminate\Support\Traits\ForwardsCalls;
class HigherOrderIfProxy
{
use ForwardsCalls;
public function __construct($target)
{
$this->target = $target;
}
public function __call($method, $parameters = [])
{
if ($this->forwardCallTo($this->target, $method, $parameters)) {
return $this->target;
}
return new class {
public function __call($method, $parameters =[])
{
// do nothing!!!
}
};
}
}
<?php
namespace Tests\Feature;
use App\HigherOrderIfProxy;
use PHPUnit\Framework\TestCase;
class HigherOrderIfProxyTest extends TestCase
{
function test_do()
{
$mock = new MockClass;
$hasRan = false;
$this->assertFalse($hasRan);
$mock->do(function () use (&$hasRan) {
$hasRan = true;
});
$this->assertTrue($hasRan);
}
function test_if_passes()
{
$mock = new MockClass;
$hasRan = false;
$this->assertFalse($hasRan);
$mock->if()->isTrue()->do(function () use (&$hasRan) {
$hasRan = true;
});
$this->assertTrue($hasRan);
}
function test_if_fails()
{
$mock = new MockClass;
$hasRan = false;
$this->assertFalse($hasRan);
$mock->if()->isFalse()->do(function () use (&$hasRan) {
$hasRan = true;
});
$this->assertFalse($hasRan);
}
}
class MockClass
{
public function if($closure = null)
{
return new HigherOrderIfProxy($this);
}
public function isTrue()
{
return true;
}
public function isFalse()
{
return false;
}
public function do($closure)
{
$closure->__invoke();
}
}
<?php
namespace App;
trait Iffable
{
public function getIfAttribute()
{
return new HigherOrderIfProxy($this);
}
public function if()
{
return new HigherOrderIfProxy($this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment