Page 1 of 2

Method or Property Transparency

Posted: Fri Aug 11, 2006 3:21 am
by Ollie Saunders
I have this bit of code

Code: Select all

public function equal($member, $value, $limit = 0)
{
    $limitChk = 0;
    if (self::_isMemberMethod($member)) {
        for ($i=0; $i<$this->_size; $i++) {
            if ($this->_array[$i]->$member() == $value) {
                $this->_mask[$i] = $this->_state;
                $limitChk++;
                if ($limitChk == $limit) {
                    break;
                }
            }
        }
    } else {
        for ($i=0; $i<$this->_size; $i++) {
            if ($this->_array[$i]->$member == $value) {
                $this->_mask[$i] = $this->_state;
                $limitChk++;
                if ($limitChk == $limit) {
                    break;
                }
            }
        }
    }
}
$member is a string that can be referring to either a method or a property. self::_isMemberMethod($method) returns true if it is a member and false otherwise. I need to perform the same loop either way but obviously one with () and one without, as you can see this is what I am doing.

The repetition of this is stark. I thought of using eval but I don't like that very much. Are there any suggestions as to how I should improve the repetition?

Posted: Fri Aug 11, 2006 3:55 am
by Weirdan

Code: Select all

public function equal($member, $value, $limit = 0)
{
    $limitChk = 0;
    $method = self::_isMemberMethod($member);
    for ($i=0; $i<$this->_size; $i++) {
        $element = $this->_array[$i];
        if ( ($method ? $element->$member() : $element->$member) == $value ) {
            $this->_mask[$i] = $this->_state;
            if (++$limitChk >= $limit)
                break;
        }
    }
}

Posted: Fri Aug 11, 2006 4:10 am
by Ollie Saunders
Superb.
Why didn't I think of that?

Not that I'm complaining or anything but I would just like to note that with '?' the truth evaluation of $method is repeated for every iteration of the loop.

Posted: Fri Aug 11, 2006 4:15 am
by Weirdan
Not that I'm complaining or anything but I would just like to note that with '?' the truth evaluation of $method is repeated for every iteration of the loop.
That's the price of removing second loop. Since the $method is Boolean, the price perhaps isn't high enough to consider.

Posted: Fri Aug 11, 2006 4:17 am
by Weirdan
you may simplify it further as :

Code: Select all

for ($i=0; $i<$this->_size; $i++) {
        $property = $this->_array[$i]->$member;
        if ( ($method ? $property() : $property) == $value ) {
            $this->_mask[$i] = $this->_state;
            if (++$limitChk >= $limit)
                break;
        }
    }

Posted: Fri Aug 11, 2006 4:21 am
by Ollie Saunders
That's the price of removing second loop. Since the $method is Boolean, the price perhaps isn't high enough to consider.
No, it isn't. I'm using it, thanks! :)
you may simplify it further as:

Code: Select all

$property = $this->_array[$i]->$member;
I'm not sure that will work Weirdan, if $member is a method then you will get an undefined property error surely?

Posted: Fri Aug 11, 2006 4:27 am
by Weirdan
I'm not sure that will work Weirdan, if $member is a method then you will get an undefined property error surely?
Image
...just used to work with functions as first-class values Image

Posted: Fri Aug 11, 2006 4:29 am
by Ollie Saunders
Hmmmm OK got more repetition to solve now hehehe = : - P

Code: Select all

public function equal($member, $value, $limit = 0)
    {
        $limitChk = 0;
        $isMethod = self::_isMemberMethod($member);
        for ($i=0; $i<$this->_size; $i++) {
            $elem = $this->_array[$i];
            if (($isMethod ? $elem->$member() : $elem->$member) == $value) {
                $this->_mask[$i] = $this->_state;
                if (++$limitChk >= $limit) {
                    break;
                }
            }
        }
    }
    public function identicial($member, $value, $limit = 0)
    {
        $limitChk = 0;
        $isMethod = self::_isMemberMethod($member);
        for ($i=0; $i<$this->_size; $i++) {
            $elem = $this->_array[$i];
            if (($isMethod ? $elem->$member() : $elem->$member) === $value) {
                $this->_mask[$i] = $this->_state;
                if (++$limitChk >= $limit) {
                    break;
                }
            }
        }
    }
    public function greaterThan($member, $value, $limit = 0)
    {
        $limitChk = 0;
        $isMethod = self::_isMemberMethod($member);
        for ($i=0; $i<$this->_size; $i++) {
            $elem = $this->_array[$i];
            if (($isMethod ? $elem->$member() : $elem->$member) > $value) {
                $this->_mask[$i] = $this->_state;
                if (++$limitChk >= $limit) {
                    break;
                }
            }
        }
    }
    public function lessThan($member, $value, $limit = 0)
    {
        $limitChk = 0;
        $isMethod = self::_isMemberMethod($member);
        for ($i=0; $i<$this->_size; $i++) {
            $elem = $this->_array[$i];
            if (($isMethod ? $elem->$member() : $elem->$member) < $value) {
                $this->_mask[$i] = $this->_state;
                if (++$limitChk >= $limit) {
                    break;
                }
            }
        }
    }
Thinking about __call() but that would involve a switch (either slow or still bulky) or eval (bit greasey all over).
Weirdan, to the rescue? :P

Posted: Fri Aug 11, 2006 4:36 am
by Weirdan
make general iteration method and pass a comparator to it

Posted: Fri Aug 11, 2006 4:43 am
by Ollie Saunders
I'd have to use eval then.

Posted: Fri Aug 11, 2006 4:49 am
by Weirdan
I'd have to use eval then.
not really, either variable function or call_user_func would be sufficient

Posted: Fri Aug 11, 2006 4:51 am
by volka
There's never a "have to use eval then" ;)

Posted: Fri Aug 11, 2006 4:55 am
by Weirdan
There's never a "have to use eval then"
Extremely argueable position. Eval is there for a reason, just like any other function in PHP. But it's being used in all the wrong ways possible though...Image

Posted: Fri Aug 11, 2006 4:59 am
by Benjamin
You both have some weird looking avatars lol.

Posted: Fri Aug 11, 2006 5:02 am
by Ollie Saunders
astions wrote:You both have some weird looking avatars lol.
Thanks. I do find the hedgehog genitals somewhat disturbing however = : - P