- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Thats actually what I was thinking about. if the $ isn't there then even a partial match at the start will do. either way, using a regex for something like that is idiotic. They should only be used where complex formats are used and even then, only if those formats can not reasonably be abstracted out to data structures due to circumstances.
Admin
If the array is ordered (I wonder, is it?) they could even go with a binary search. either way, almost anything will be faster than reading the entire array, going through several type conversions, and then remaking a string... to let a regexp read the entire array again.
Admin
Constants [0] { }
Static properties [0] { }
Static methods [0] { }
Properties [6] { Property [ <default> protected $message ] Property [ <default> private $string ] Property [ <default> protected $code ] Property [ <default> protected $file ] Property [ <default> protected $line ] Property [ <default> private $trace ] }
Methods [9] { Method [ <internal> final private method __clone ] { }
Method [ <internal, ctor> public method __construct ] {
Method [ <internal> final public method getMessage ] { }
Method [ <internal> final public method getCode ] { }
Method [ <internal> final public method getFile ] { }
Method [ <internal> final public method getLine ] { }
Method [ <internal> final public method getTrace ] { }
Method [ <internal> final public method getTraceAsString ] { }
Method [ <internal> public method __toString ] { } } }
Admin
The real WTF is that he tried to concatenate a long, orange vegetable root to a string instead of a caret.
Yeah, I know it's been mentioned already, but come on...
Admin
. . . and there I was, waiting for the canonized path to explode. . .
Admin
since when was 0.5 between 1 and 10.
there is a wtf :p
Admin
Sure, but I'll use some simpler code to explain. Let
be an array. The Array class defines an 'each' method, that allows constructs like . 'each' is an iterator, and just returns elements from the array.The fragment
is called a block, and in this case is acting like an anonymous subroutine. The syntax declares that p is a formal parameter for the block -- that is, p is bound to the block.You can implement closures, coroutines, continuations, etc using blocks like this..
Admin
One problem I haven't seen anyone mention yet is that by stuffing the pathnames into a regexp, you interpret them as regexps. This means, for example, that the dot (.) is treated as a wildcard character and will match any letter in the base path.
The code could even die horribly if a pathname contained something awful such as an unmatched parenthesis.
Admin
Roughly this code in PHP, in case anyone's from that side of the fence is still having trouble following it:
Note caveats; array_map() only works on arrays (Ruby will just call the each() method if you've mixed in Enumerable) and only accepts named functions as arguments (create_function() returns one if you want to specify it inline, but that will make a new one each execution as well as being fugly).
If the array_map() confuses you (heh), it could also be written in the arguably more "phpish":
Note the lack of preg_escape() on paths, and the missing subexpression or need for '|^' in the join() so each potential match is anchored correctly. Also note the regexp could get rather large. Low on the WTF scale really; haven't you guys seen plain old marginally broken poor code before?
Admin
(And yes, the other caveat is "/" normally appears in paths, making the lack of escaping metacharacters more of a problem, hence my uncompleted replacing of // with ##).
Admin
Okay, maybe I am a bit rusty on Regular Expressions (or too lazy to decipher them for the purpose of reading a WTF posting) and inexperienced on Ruby, but I don't see the WTF.
I understand that the guy's code wasn't the best way to do this, but rolling your own instead of using a built in method is a pretty run-of-the mill programmer mistake. It doesn't seem to rise to the level of a WTF like using using HD files instead of variables because you don't trust them.
Admin
When I write like this, people accuse me of being a Pascal hack, which I am <G>
I do not understand people who are proud of obtuse and cryptic code (Perl, Lisp, etc.)
Admin
base.match(/^#{ActionController::Routing.controller_paths.map { |p| File.expand_path(p) } * '|'}/)
The map function has the same purpose as PHP's array_map function. In Ruby syntax, { |foo| ... } is an anonymous function (or "block", in Ruby terms), where |foo| is the parameter list. So, it takes ActionController::Routing.controller_paths, calls File.expand_path on each element, and builds a new array of the results.
Next, the multiplication operator is applied to that array and '|', performing the same job as PHP's join() or implode() function.
The #{} syntax can appear in strings or regex literals. Ruby evaluates the code inside the #{} and inserts it into the string or regex.
That leaves base.match(/^some regex/), which needs no explanation.
Admin
So, you got me. I assumed the path should be fixed, not a prefix. But the RegExp will still let /usr/good/path/../../bad/path through, right? (Or is this path canonized before it gets to the check function?)
Essentially, lazily compiling the expression (and adding parentheses) will just produce the equivalent of a prefix-tree lookup, which should run O(log n).
Admin
Yes, a period could be a problem. Ruby is, however, smart enough to escape the / character for you.
They should have used Regexp#escape though.
Admin
Does Ruby boast about its TIMTOWTDI luxury(?!) like Perl does?!
IMHO, more often than not, people stop trying to make their code more readable - forget about optimizing - simply because they can always attribute it to tim-toady.
Admin
Admin
Hmm, many people are arguing about the use of "any?" or "starts_with?", but that is wrong. As I mentioned in the submission, "match" does a full match, not a search!
Don't be confused with the caret (only in the first alternative) and the missing dollar at the end. It's just a hasty copy from the original function.
You can see that also from the intended functionality: base should be one of those controller_paths, not just start with one.
And as for the "quality" of this WTF:
Admin
yes, but the community usually also say that there is a best way to do it as well.
that's not really my experience with ruby. more often than not I find it easy to understand, except for when someone else has been OTT clever with their code.
Admin
Anybody or any language that uses a 'goto' should be shot on sight. Not to mention using a 'for' loop when you do not necessarily know if you want to iterate through the entire data structure. I'm not a great programmer, but please people, can we not at least try to be civilized?
Admin
I don't need for that code to have gotos. It's in VB, so I'd shoot it anyway. ;) (And remember, if you're doing assembler, JMPs are GOTOs in microcode!!!)
I've used C, C++, Foxpro (ah, the old days), BASIC (before M$ crapped on it and produced VB), LISP, APL, PHP, Java, Prolog and x86 assembly code.
LISP, APL and Prolog have their specific uses, so I wouldn't diss that much on them; APL kind of makes sense (and I love to do complex operations on it, I can do entire complex operations with one line!), so does Prolog, but LISP just makes me dizzy.
For real-work languages, I prefer something I can actually read, so I'd go for something similar to C (which is why I do C++ or Java mostly these days).
I got lost with that small snippet for Ruby, so I doubt I'll use that in the near future.
Admin
that's probably some of the most esoteric ruby code you will ever see... as they say, you can write fortran in any language... but most ruby is significantly more human readable...
Admin
Good Lord, that's ugly. This is why it took me so long to catch on to Ruby: While it is possible to write nice, clean Ruby, the practice is discouraged. wink
Seriously, I'm beginning to feel comfortable with the language, and I had to grab my Pickaxe book and puzzle through it. Talk about going to a lot of trouble to make a one-liner...
Admin
Right on! Just because you can do it on one line doesn't mean you should. I thought I was the only one who thought code should be easy to read, even at the expense of being 1337 efficient and kewl.
Admin
he said by default, you monkey.
Admin
Why, no, not at all: "It's OK to figure out murder mysteries, but you shouldn't need to figure out code. You should be able to read it." - Steve C McConnell
Admin
Or in LISP, a complex tree of conses.
On the plus side, that abuse was easy to spot: c(a|d){3,}r
Admin
Someone should submit a fix to the Rails team, get some recognition for yourself!
Admin
Can the paths contain any characters that would be meaningful in a regular expression? Because they will be interpreted as such, not taken literally:
(That would have answered 'nil' if it hadn't matched.)
Do the paths come from the environment? Of course, even if they did, there would be no way for a remote web user to inject anything, but still, it's not the right way to go....