SitePoint Sponsor

User Tag List

Page 3 of 3 FirstFirst 123
Results 51 to 62 of 62
  1. #51
    SitePoint Wizard silver trophybronze trophy Stormrider's Avatar
    Join Date
    Sep 2006
    Location
    Nottingham, UK
    Posts
    3,133
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    From everything I've read about metaprogramming, it sounds like a horrible way to code. Sounds like a bad idea to me.

  2. #52
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    351
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by Stormrider View Post
    From everything I've read about metaprogramming, it sounds like a horrible way to code. Sounds like a bad idea to me.
    I wont say so, it helps a lot with a plugin system. In fact, there are certain jobs that can only be accomplished with Metaprogramming.

  3. #53
    SitePoint Wizard silver trophybronze trophy Stormrider's Avatar
    Join Date
    Sep 2006
    Location
    Nottingham, UK
    Posts
    3,133
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Like what?

  4. #54
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    351
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    Oh yeah, just found out that PHP's OOP has another flaw in it, this time it involves callable objects/methods. The problem is that __invoke() does not apply to class/object attributes, it only works for standard string variables. Consider a plugin system shown like below:

    Class UserController:
    PHP Code:
    class UserController{

        public function 
    add(){
            echo 
    "Creating User...<br>";
        }

        public function 
    edit(){
            echo 
    "Updating User...<br>";
        }

        public function 
    delete(){
            echo 
    "Removing User...<br>";
        }


    UserSearchPlugin:
    PHP Code:
    class UserSearchPlugin{

        public function 
    __invoke(){
            echo 
    "Searching User....<br>";
        }

    The code below will throw a fatal error:
    PHP Code:
    $controller = new UserController;
    $controller->search = new UserSearchPlugin();
    $controller->search(); 
    While it will work if you modify it a bit, but the code will look a lot more ugly:
    PHP Code:
    $controller = new UserController;
    $controller->search = new UserSearchPlugin();
    $search $controller->search;
    $search(); 
    Of course some may argue that invoking class/object property could override their methods, that happens when you have a property and a method sharing the same name. This can be a fatal collision issue, but my question is, do you even think its a good OO design if for some reason your class/object has properties with the same name as its methods? At least I dont think so, while apparently the way PHP prevents metaprogramming and this method invocation mechanism is making it almost impossible for me to design a proper plugin system for my application. *sigh*

  5. #55
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    689
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    So is $controller->search->invoke() really that ugly?

    And do keep in mind that very few OOP systems will allow $controller->search = new UserSearchPlugin(); without declaring the instance variable.

  6. #56
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    351
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    Well the fact is that my controller is invoking each action in this way: $controller->$action(), which is why the fact that __invoke() does not work with class/object properties is a huge blow. Maybe few OOP systems allows you to set property on the fly, but many enable metaprogramming so adding methods on the fly is easier. I was just trying to emulate metaprogramming with PHP, its just not that easy.

    I do find a workaround for the plugin problem though, it requires using magic method __call() and therefore can be heavy on performance.

    PHP Code:
    class UserController{

        public function 
    __call($method$params){
            if(
    property_exists($this->$method)){
                
    $method $this->method;
                
    $method();
            }
        }

        public function 
    add(){
            echo 
    "Creating User...<br>";
        }

        public function 
    edit(){
            echo 
    "Updating User...<br>";
        }

        public function 
    delete(){
            echo 
    "Removing User...<br>";
        }


    Then $controller->$action() will work, its not a pretty solution but it does the work for now.

  7. #57
    SitePoint Addict
    Join Date
    Aug 2013
    Location
    New Zealand
    Posts
    277
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    I wonder if Python or Ruby has found ways to resolve this problem? Or is this a universal problem for all dynamically typed languages?
    From my observation python seems to use zope.interface. (maybe there are others.)

    Sent from my XT316 using Tapatalk 2

  8. #58
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    Well the fact is that my controller is invoking each action in this way: $controller->$action()
    You may get better and more consistent results with call_user_func_array. That way, you can execute anything that's callable, including an invokable object.
    "First make it work. Then make it better."

  9. #59
    SitePoint Addict
    Join Date
    Aug 2013
    Location
    New Zealand
    Posts
    277
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    I do find a workaround for the plugin problem though, it requires using magic method __call() and therefore can be heavy on performance.

    PHP Code:
    class UserController{

        public function 
    __call($method$params){
            if(
    property_exists($this->$method)){
                
    $method $this->method;
                
    $method();
            }
        }

        
    // ... snip for brevity ...

    Maybe I'm missing something but what's the downside to overriding the __call method? Is there a huge performance penalty? Or are any database methods used still going to dominate any performance issues here unless you're database is completely in memory?

    From an OOP vantage point it certainly seems to give you the polymorphism that you are after.

    I am not sure I am understanding here but is it being claimed, in this thread, that metaprogramming would be a high performance way of implementing a plugin handling framework in PHP or is it code elegance that is the driving factor here?

    Sent from my XT316 using Tapatalk 2

  10. #60
    SitePoint Addict bronze trophy
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    351
    Mentioned
    6 Post(s)
    Tagged
    1 Thread(s)
    Well there is indeed a significant performance penalty of using __call() and call_user_func_array(), using two of them together makes this even worse. The result is evident from Mark O'Sullivan's article:
    http://markosullivan.ca/benchmarking-magic-revisited/

    Id say the worst practice is to implement call_user_func_array() inside __call() magic method, it cant get slower than using these two together although implementing them separately.

  11. #61
    SitePoint Addict
    Join Date
    Aug 2013
    Location
    New Zealand
    Posts
    277
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    Well there is indeed a significant performance penalty of using __call() and call_user_func_array(), using two of them together makes this even worse. The result is evident from Mark O'Sullivan's article:
    http://markosullivan.ca/benchmarking-magic-revisited/

    Id say the worst practice is to implement call_user_func_array() inside __call() magic method, it cant get slower than using these two together although implementing them separately.
    Yeah, I read that article and it looks pretty bad using both those methods together and he seemed to favor using variable number of arguments passed to the method.

    Apart from the fact that this is a fairly bad look for PHP I wonder how many plugins are cpu bound rather than database access bound as you would have to be calling those plugin methods a lot to incur that 17 second penalty.

    Sent from my XT316 using Tapatalk 2

  12. #62
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,246
    Mentioned
    16 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Hall of Famer View Post
    Well there is indeed a significant performance penalty of using ... call_user_func_array()
    Just to make sure we're clear, "significant" here means as little as 1 microsecond (Larry Garfield's test) or as much as 5 microseconds (Paul M Jones's test). Don't forget that they iterate their tests to accumulate numbers that actually look significant. In Larry's case, he used 2 million iterations.
    "First make it work. Then make it better."


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •