• zephc (cs)

    Hah, i like how s/he used os.path.join() in the constructor. Maybe the guy was a Perl programmer, and wanted MTOWTDI. I also like how that class was only used a few times in the project, further invalidating the time spent on it.

    Operator overloading definitely has its advantages, but this is just silly.

    6/10 on the WTF meter, IMO.

  • Daruku (unregistered)

    huh?

  • Ytram (cs)

    I'm dying to know what language this is.  It looks like the bastard child that would come from an unholy union of C++ and VB

  • Dave (unregistered) in reply to Ytram

    It's python, which is actually the bastard child of Java and Perl.

  • aberant (unregistered)

    looks like python to me...

  • Davidp (unregistered)

    I'm sorry but this WTF is too obscure and dense to parse.  Where exactly are the WTFs?

  • JAFO (unregistered) in reply to Ytram

    This is Python, sweet glorious python and until you get in and do it, you won't realize what a beautiful and powerful language it is.

    The syntax is a breeze and quite readable as a general rule.

  • YAFO (unregistered) in reply to JAFO

    The WTF is that every operator, accessors and mutators, are overridden to actually append to the string. The comment alone explains it.

    I think that "least surprise" principle was violated severly, and will be aching for days.

  • Laz (unregistered) in reply to Davidp
    Anonymous:
    I'm sorry but this WTF is too obscure and dense to parse.  Where exactly are the WTFs?


    ^^^ What he said...
  • JAFO (unregistered) in reply to Dave
    Anonymous:
    It's python, which is actually the bastard child of Java and Perl.
    No, not at all. Python began in 1990. Java/Oak began in 1991

    Short python overview

  • Ayende Rahien (cs) in reply to Davidp

    Well, there is the use of operator overloading when you don't need them.
    There is the aweful syntax that you get path("Users")"Ayende"() ???!!!

  • Unindicted coconspiritor (unregistered) in reply to zephc

    <i>Maybe the guy was a Perl programmer, and wanted MTOWTDI.</i>

    Ding ding ding ding ding!

  • Jake P (unregistered)

    Ok, I'll bite and defend this one.

    The general idea isn't too bad.  If they get rid of getattr and replace add with div, they get a program where operator overloading actually makes some sense.  At the very least, it makes paths more readable:


    a = path("a");
    b = path("b");
    c = a/b;


    Been done before by others... I would just use the standard path manipulators myself.

  • endothermal (unregistered) in reply to Jake P

    Anonymous:
    Ok, I'll bite and defend this one.

    The general idea isn't too bad.  If they get rid of __getattr__ and replace __add__ with __div__, they get a program where operator overloading actually makes some sense.  At the very least, it makes paths more readable:


    a = path("a");
    b = path("b");
    c = a/b;


    Been done before by others... I would just use the standard path manipulators myself.

    assuming c would equal "a/b" or a simpler example

    a=path("/inittech");

    b=path("superprogram")

    c=a/b

    c would then equal  "/inittech/superprogram"

    I see your point with the / operator, but it really would confuse the hell out of a new programmer reading the code for the first time.  Unless the consumer of the class has access to the code I would probably avoid using operator overloading like that.

  • zephc (cs)

    I also wanted to say that if you've never seen Python before, don't let this WTF taint it for you. It's a great language, and this is a terrible way to experience it. Python tends to be very readable, yet powerful.

    To explain each part: The methods with the two underscores are reserved in Python such that

    "this is" + " my name" is the same has "this is".add(" my name") (Aside: Notice that literals can have methods called upon them)

    http://www.network-theory.co.uk/docs/pylang/ref_32.html has a good summary of these reserved methods.

  • Charles Nadolski (cs) in reply to Unindicted coconspiritor
    Anonymous:
    Maybe the guy was a Perl programmer, and wanted MTOWTDI.

    Ding ding ding ding ding!

    <font size="4">
    For those too lazy to google, the acronym means </font><font size="-1"><font size="4">More Than One Way To Do It, which I thought was something to AVOID in programming. Even in C++ I get annoyed that you can use *(SomeArray+i) and SomeArray[i] in the same statement, which do the same thing but are two different concepts (pointer arithmetic versus array iteration).  Now you can use 10 different syntaxes to put strings together! WOOT!</font>
    </font>
  • DannyB (unregistered) in reply to Charles Nadolski

    In C and C++, you can actually use i[SomeArray].

    Try it!

  • Ytram (cs) in reply to zephc
    zephc:
    (Aside: Notice that literals can have methods called upon them)


    .NET and Java both support this as well.  It can be a useful way to avoid null reference exceptions.
  • Sean Connery (unregistered) in reply to zephc
    zephc:
    Hah, i like how s/he used os.path.join() in the constructor. Maybe the guy was a Perl programmer, and wanted MTOWTDI. I also like how that class was only used a few times in the project, further invalidating the time spent on it. Operator overloading definitely has its advantages, but this is just silly. 6/10 on the WTF meter, IMO.


    Tell Boost that http://www.boost.org/libs/filesystem/doc/
  • Jake (unregistered) in reply to DannyB
    Anonymous:
    In C and C++, you can actually use i[SomeArray].

    Try it!



    Thats because all the [] operator does is take your i and your SomeArray, add them together and dereference the result.  Since addition is commutative, you get interesting results such as you pointed out.
  • JamesCurran (cs) in reply to DannyB

    Anonymous:
    In C and C++, you can actually use i[SomeArray].

    Anonymous:
    (Aside: Notice that literals can have methods called upon them)

    And of course we can combine these so that

    "ABCD"[2] == 2["ABCD"] == 'C'

     

  • WTFer (cs)

    And of course if we are talking of the ugly curiosities of C we can never forget the Duff Device.

  • pycoder (unregistered) in reply to WTFer

    getitem = getattr Auch , beautifull WTF ! It must be a perl or php coder

  • Hank Miller (unregistered)

    Thats it?   It doesn't do anything.  

    I could see many reasons to write a class to do this, but all of them abstract something system specific.   For instance if it wrapped the path to the configuration file, and made sure it was hidden, no matter what the OS, this would make sense (that is when accessed it set the hidden bit on Windows, while starting the filename with a '.' on Unix.)

    <font>path("project")a.b.c.super() -> "project/a/b/c/super"
    </font>

    God help the unix person with no python skills who is thinking
    "project/a.b.c.super"

    Of for that matter someone who is thinking a that this is violating abstraction by going down a long chain of member classes to call c.super()

  • Aristotle Pagaltzis (cs) in reply to zephc
    zephc:
    Maybe the guy was a Perl programmer, and wanted MTOWTDI.

    Err, unlikely. No Perl programmer would use overloading to begin with. And any self-respecting Perl programmer relies on File::Spec, which Python’s os.path roughly corresponds to.

    Larry’s own corollary to TMTOWTDI is “but not all ways are created equal.” The multiple options exist so you can pick the one which most clearly conveys intent, not to make your code more varied and exciting. If you don’t trust your restraint and sense of style, then not having options will obvious be desirable and Perl is not for you.

    This WTF smells like a C++ programmer’s doing to me.

  • loneprogrammer (cs) in reply to Aristotle Pagaltzis

    All the people trying to plug their favorite language need to shut up.

    The only language that matters is binary code.  Everything else is just shorthand for it.

  • Xepol (cs)

    Uh, for those wondering where the wtf is, its because path("project", "super")() is probably longer to type than "project/super", makes you wonder, in fact, there does not appear to be ANY circumstances where this reduces typing, simplifies code or avoids bugs. Its more of a why than a what, as in why the F* would anyone bother?!?

    Err,as to the suggesting to google MTOWTDI, why would I want to google a headroll on the keyboard? TIAPAWAGTLTBMOU! (There is a point at which acronyms get too long to be meaningful or useful.)

    Mind you, having been through the education system with REAL programming experience before hand (I was the annoying guy there to get the piece of paper after already having a consulting career), I have to say, most institutions turn out people barely able to write hello world and expect them to get 60K a year jobs. It is no surprise that a lot of code looks like it was written by a spastic chimp.

  • tim the enchanter (unregistered) in reply to loneprogrammer
    loneprogrammer:
    The only language that matters is binary code.  Everything else is just shorthand for it.


    actually, they're longhand for it. the binary code is the base level, the languages on top are more complex and there to make life 'better' for anyone that doesn't have bits for brains.
  • Aristotle Pagaltzis (cs) in reply to Xepol
    Xepol:
    Uh, for those wondering where the wtf is, its because path("project", "super")() is probably longer to type than "project/super", makes you wonder, in fact, there does not appear to be ANY circumstances where this reduces typing, simplifies code or avoids bugs.

    Err. Try again. On Windows, that would be project\super. And MacOS Classic, it would be projects:super. That is what os.path.join is all about: system-independent filename manipulation. The WTF is that he writes an elaborate bunch of crap to be able to say path("project")["super"] where it should be simply os.path.join("project","super").

  • phelyan (cs) in reply to Aristotle Pagaltzis
    Aristotle Pagaltzis:
    Xepol:
    Uh, for those wondering where the wtf is, its because path("project", "super")() is probably longer to type than "project/super", makes you wonder, in fact, there does not appear to be ANY circumstances where this reduces typing, simplifies code or avoids bugs.

    Err. Try again. On Windows, that would be project\super. And MacOS Classic, it would be projects:super. That is what os.path.join is all about: system-independent filename manipulation. The WTF is that he writes an elaborate bunch of crap to be able to say path("project")["super"] where it should be simply os.path.join("project","super").

    What gets me is the fact that he actually uses os.path.join in the code...

  • Fishy5 (unregistered) in reply to phelyan
    phelyan:
    Aristotle Pagaltzis:
    Xepol:
    Uh, for those wondering where the wtf is, its because path("project", "super")() is probably longer to type than "project/super", makes you wonder, in fact, there does not appear to be ANY circumstances where this reduces typing, simplifies code or avoids bugs.

    Err. Try again. On Windows, that would be project\super. And MacOS Classic, it would be projects:super. That is what os.path.join is all about: system-independent filename manipulation. The WTF is that he writes an elaborate bunch of crap to be able to say path("project")["super"] where it should be simply os.path.join("project","super").

    What gets me is the fact that he actually uses os.path.join in the code...

    That would be because he can't assume that he needs to use "/".
  • Simon (unregistered) in reply to Jake P
    Anonymous:
    Ok, I'll bite and defend this one.

    Been done before by others... I would just use the standard path manipulators myself.



    Indeed. The path Python module is a good example.


  • Ralph Loizzo (unregistered) in reply to DannyB

    You know, I forgot about that i[SomeArray]...

    can anyone explain to me again why this works in c/c++?

    index[SomeArray]
    it seems like it should ONLY work as SomeArray[index]

    What's going on behind the scenes?

  • Ralph Loizzo (unregistered) in reply to Ralph Loizzo

    Oops...

    should have scrolled down for the answer!

    Sorry...

  • e (unregistered) in reply to Ytram

    Ytram:
    I'm dying to know what language this is.  It looks like the bastard child that would come from an unholy union of C++ and VB

    People seem to ask this every time. How about including which language it is in the post description for each WTF?

  • DZ-Jay (cs) in reply to Ralph Loizzo
    Anonymous:
    You know, I forgot about that i[SomeArray]...

    can anyone explain to me again why this works in c/c++?

    index[SomeArray]
    it seems like it should ONLY work as SomeArray[index]

    What's going on behind the scenes?


    Its actually pretty simple and straightforward:

    In the expression SomeArray[index], the SomeArray part represents (i.e. translates/compiles to) a pointer to the base memory location of the array SomeArray, and the index part represents an offset from this base location.  So the expression evaluates finally to a pointer to "base-location SomeArray + offset index".

    Conversely, in the expression index[SomeArray], the index part is evaluated as a pointer to the base memory location of a supposed array called index, while the SomeArray part is evaluated as an offset from this base location.  This expression represents a pointer to "base-location index + offset SomeArray".

    The reason that this works is because, in a very technical way, it is just pointer arithmetic, and by the commutative property of addition, "SomeArray + index" = "index + SomeArray".

    I say in a "very technical way", because conceptually, "SomeArray + index" (i.e. SomeArray[index]) is the correct way of viewing at it, as the index[SomeArray] makes no semantic sense.

        dZ.

  • Irrelevant (cs)

    Actually, I think that index[some_array] only works if sizeof(*some_array) == 1.

    some_array[index] is the same as *(some_array + index * sizeof(*some_array)), not *(some_array + index). Implicitly casting a non-pointer to a pointer gets you a void *, so sizeof(*not_a_pointer) is the same as saying sizeof(void). This doesn't make sense, so is generally taken to be 1 as a fallback.

    So, index[some_array] is good for obfuscating access to your char *s, but not much else.

  • JamesCurran (cs) in reply to Irrelevant
    Irrelevant:

    Actually, I think that index[some_array] only works if sizeof(*some_array) == 1.

    Nope.  This correctly prints "3.0000":

    <FONT color=#0000ff size=2>

    int</FONT><FONT size=2> main(</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2> argc, </FONT><FONT color=#0000ff size=2>char</FONT><FONT size=2>* argv[])
    </FONT><FONT size=2>{
    </FONT><FONT color=#0000ff size=2>      float</FONT><FONT size=2> arr[5] = {1.0,2.0,3.0,4.0,5.0};
          printf (</FONT><FONT color=#800000 size=2>"%f"</FONT><FONT size=2>, 2[arr]);
    </FONT><FONT color=#0000ff size=2>      return</FONT><FONT size=2> 0;
    }

    </FONT>
  • J (unregistered) in reply to Xepol

    Err,as to the suggesting to google MTOWTDI, why would I want to google a headroll on the keyboard?

    Come on fhqwhgads.

  • Suomynona (unregistered) in reply to Irrelevant
    Irrelevant:

    Actually, I think that index[some_array] only works if sizeof(*some_array) == 1.

    some_array[index] is the same as *(some_array + index * sizeof(*some_array)), not *(some_array + index). Implicitly casting a non-pointer to a pointer gets you a void *, so sizeof(*not_a_pointer) is the same as saying sizeof(void). This doesn't make sense, so is generally taken to be 1 as a fallback.

    So, index[some_array] is good for obfuscating access to your char *s, but not much else.



    There is no implicit cast from non-pointer to pointer in C/C++, except for the conversion of the compile-time constant 0 to an appropriate pointer type in C++. And that doesn't produce a void *<!--<code--> unless void * happens to be appropriate in this particular expression. In C++, there is no pointer type that can be converted to any other pointer type, thus converting to that (hypothetical) type is not an option. Conceptually, that would require a "bottom type", but C++ only has a "top type" (void), which works in the opposite direction. As a side-note, void is, oddly enough, abstract, "incomplete" even, although it needn't be. Only the bottom type has to be abstract (or, alternatively, every type must include an object compatible with bottom, like in Haskell).

    As for the sizeof(...) == 1 comment: That's incorrect, it will work with element types of any size. i[p] is equivalent to p[i] in C/C++, which in turn is equivalent to *(p+i). There is no multiplication with sizeof(*p), because pointer arithmetic already performs it implicitely!

  • Drak (cs) in reply to Suomynona

    A question about this wonderful C++ code...

    I understand why array[index] works...

    But why does index[array] not end up taking the pointer to index and adding the pointer to array, leading to a very random place in memory? How does it know not to dereference index, while in the first case it does dereference array... Or am I just confused this early on Monday morning??

    Drak

  • witch (cs) in reply to Drak
    Drak:

    A question about this wonderful C++ code...

    I understand why array[index] works...

    But why does index[array] not end up taking the pointer to index and adding the pointer to array, leading to a very random place in memory? How does it know not to dereference index, while in the first case it does dereference array... Or am I just confused this early on Monday morning??



    Because it doesn't dereference the pointer array in the first place! Array is the name of the address of array, so naming it already specifies the address, no need to reference or 'get-address-of' here!

    It's confusing at first, but when you get used to it.... you use it as little as possible.

    Christ

  • Aaron (unregistered) in reply to DannyB

    That's just so stupid, it's just funny! I do feel strangely enlightened though!

  • Drak (cs) in reply to witch

    witch:

    Because it doesn't dereference the pointer array in the first place! Array is the name of the address of array, so naming it already specifies the address, no need to reference or 'get-address-of' here!

    It's confusing at first, but when you get used to it.... you use it as little as possible.

    Christ

    hmm, ok I think I understand.. so the 'value' of array is actually it's address in memory...

    Drak

     

  • dhromed (cs) in reply to Aaron

    How about defining a WTF operator, that looks like this:

    ...

  • Cynos (unregistered) in reply to JAFO

    This is Python, sweet glorious python and until you get in and do it, you won't realize what a beautiful and powerful language it is.

    The syntax is a breeze and quite readable as a general rule.


    Exactly, the WTF is that he's taken something simple and elegant, and obfuscated the shit out of it.

    There's a philosophy to Python,here's a copy.

    Some lucky b'stard actually gets to work on a Python project and does this. *sigh*
  • lucio (cs) in reply to e
    Anonymous:

    Ytram:
    I'm dying to know what language this is.  It looks like the bastard child that would come from an unholy union of C++ and VB

    People seem to ask this every time. How about including which language it is in the post description for each WTF?

    People are just too lazy to go and find out. And this was an easy one, for there's a link to http://docs.python.org/lib/module-os.path.html [:D]

    Sometimes the Java/C# confusion comes along. I usually set them apart by methodName (Java) instead of MethodName (.NET), when possible.

  • Cynos (unregistered) in reply to Fishy5
    Anonymous:
    phelyan:

    What gets me is the fact that he actually uses os.path.join in the code...

    That would be because he can't assume that he needs to use "/".



    *sigh* os.path.join() is os independent.... which means that you use it exactly when you can't assume how you'll be creating paths..... did you miss the post that said that?

    *double sigh*
  • JamesCurran (cs) in reply to Cynos
    Anonymous:
    Anonymous:
    phelyan:

    What gets me is the fact that he actually uses os.path.join in the code...

    That would be because he can't assume that he needs to use "/".


    *sigh* os.path.join() is os independent.... which means that you use it exactly when you can't assume how you'll be creating paths..... did you miss the post that said that?

    um... Whom are you talking to?  You are just repeating the same point Anonymous just made......

  • travisowens (cs)

    __________underscores______________make___________code__________more________________readable

Leave a comment on “Operator Overloading Overload”

Log In or post as a guest

Replying to comment #:

« Return to Article