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?

...just used to work with functions as first-class values

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?

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...

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