r90819 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90818‎ | r90819 | r90820 >
Date:04:50, 26 June 2011
Author:aaron
Status:resolved (Comments)
Tags:
Comment:
Made '^' (XOR) in recCheckCondition() act as a one-hot detector. Before r28805, XOR silently ignored subconds beyond the first two. After r28805, XOR passed iff an odd number of subconds passed. It now passes iff exactly one subcond passes. This should be more intuitive, as I highly doubt anyone using 3+ subconds was doing it correctly before.
Modified paths:
  • /trunk/phase3/includes/Autopromote.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Autopromote.php
@@ -87,7 +87,7 @@
8888
8989 if ( is_array( $cond ) && count( $cond ) >= 2 && in_array( $cond[0], $validOps ) ) {
9090 # Recursive condition
91 - if ( $cond[0] == '&' ) {
 91+ if ( $cond[0] == '&' ) { // AND (all conds pass)
9292 foreach ( array_slice( $cond, 1 ) as $subcond ) {
9393 if ( !self::recCheckCondition( $subcond, $user ) ) {
9494 return false;
@@ -95,7 +95,7 @@
9696 }
9797
9898 return true;
99 - } elseif ( $cond[0] == '|' ) {
 99+ } elseif ( $cond[0] == '|' ) { // OR (at least one cond passes)
100100 foreach ( array_slice( $cond, 1 ) as $subcond ) {
101101 if ( self::recCheckCondition( $subcond, $user ) ) {
102102 return true;
@@ -103,18 +103,20 @@
104104 }
105105
106106 return false;
107 - } elseif ( $cond[0] == '^' ) {
108 - $res = null;
 107+ } elseif ( $cond[0] == '^' ) { // XOR (exactly one cond passes)
 108+ $res = false;
109109 foreach ( array_slice( $cond, 1 ) as $subcond ) {
110 - if ( is_null( $res ) ) {
111 - $res = self::recCheckCondition( $subcond, $user );
112 - } else {
113 - $res = ( $res xor self::recCheckCondition( $subcond, $user ) );
 110+ if ( self::recCheckCondition( $subcond, $user ) ) {
 111+ if ( $res ) {
 112+ return false;
 113+ } else {
 114+ $res = true;
 115+ }
114116 }
115117 }
116118
117119 return $res;
118 - } elseif ( $cond[0] == '!' ) {
 120+ } elseif ( $cond[0] == '!' ) { // NOT (no conds pass)
119121 foreach ( array_slice( $cond, 1 ) as $subcond ) {
120122 if ( self::recCheckCondition( $subcond, $user ) ) {
121123 return false;

Follow-up revisions

RevisionCommit summaryAuthorDate
r90931Follow-up r90819: made XOR only work on two conditions per CR. Give a warning...aaron02:56, 28 June 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r28805Fixes for r28797....simetrical19:53, 23 December 2007

Comments

#Comment by Simetrical (talk | contribs)   14:37, 26 June 2011

This is not how xor works in programming languages or mathematics. If you xor multiple things, it is indeed true if and only if an odd number are true. If you want an "only one" operator, you shouldn't call it "^" -- that's extremely confusing.

#Comment by Aaron Schulz (talk | contribs)   18:00, 26 June 2011

I talked to Bawolff and he thought the parity based behavior was confusing too. Either it should be one-hot or just allow two things. Otherwise it's just asking for mistakes.

#Comment by Simetrical (talk | contribs)   21:55, 26 June 2011

Yes, the other behavior is also confusing. How about making '^' only work with two items, and add a new condition for "exactly one is true"? If people really want actual '^' with three or more items, they can always nest it.

#Comment by Aaron Schulz (talk | contribs)   21:57, 26 June 2011

Sounds fine by me. If there are 3+ items for '^' it should give some kind of error though (not silently ignore stuff).

Status & tagging log