> On Apr 27, 2021, at 3:07 PM, Chase Peeler <chasepee...@gmail.com> wrote:
> 
> As someone mentioned above, maybe they want to just add some logging
> capabilities to maybe.
> class MyMaybe extends Maybe {
>  protected $logger;
>  public function setLogger($logger){ $this->logger = $logger; }
>  public function value(){
>     if(null !== $this->logger){ $this->logger->log("getting value"); }
>     return parent::value();
>  }
> }

That is one argument. But maybe that argument points to the need for a 
different feature, one that could be considered for PHP instead of limiting the 
freedom of the library/framework author to decide how their code will be used?

We could add an Events feature that would allow users of a class to run a 
closure before or after every time a class' methods are run?  People often 
suggest that attributes can be used to implement such features but then 
attributes can only be added by the author of the class, not injected by users 
of the class.

Imagine if something like the following existed (I just spitballed the syntax 
as a straw man suggestion; I doubt an actual events feature would look much 
like this after requirements were fleshed out):

/* 
 * Attach an event to run *after* every time the Maybe class was instantiated
 */
\PHP\Events::after( [ Maybe::class, "__construct" ], func($context){
    // Attach a property to the instance that would only be visible inside of 
events
    $context->logger = MyLogger::get();
})

/* 
 * Attach an event to run *before* every time the value() method was called an 
a Maybe instance
 */
\PHP\Events::before( [ Maybe::class, "value" ], func($context){
    // Call log() on the attached $logger property
    $context->logger->log("getting value");
})

/* 
 * Your logger class
 */
class MyLogger {
   private static $logger;
   public static function set($logger){
     self::$logger = $logger;
   }
   public static function get(){
     if (!isset(self::$logger)) {
        self::$logger = new MyLogger();
     }
     return $logger;
   }
   public static function log($msg){
     printf( "$1\n", $msg );
   }
}

/* 
 * Example usage code
 */
$m = new Maybe(1)
echo $m->value();   // echos "getting value\n1"


In my view this would be more consistent with the open-closed principle of 
S.O.L.I.D. because it would allow a developer to augment classes in libraries 
and frameworks that hardcode instantiate — do not just dependency injection — 
something you cannot do with mere subclassing.

I know this suggestion is off-topic for this thread, but I introduce to point 
out at least some of the objections to `sealed` could addressed better by new 
language features.  

SO IF people are interested in discussing this specific language feature more, 
PLEASE break this off into a different thread.

-Mike
P.S. Also, I admit I did what I hate when other people do it; I focused on your 
example that you used to illustrate a general principle and I addressed that 
example only, not your general concern. But I only did so because other 
features would better address that specific example.  

Do you have other examples that would illustrate why you might want to extend a 
Maybe class that could not be handled with events?

Reply via email to