• (nodebb)

    When you add in indirect capabilities, it works as a simple re-director....

  • Berg (unregistered)

    This looks like it was added to an API for testing deployments. They could make something like a /healthcheck endpoint, but this may also get the job done.

  • MaxiTB (unregistered)

    This actually makes sense in some case.

    Consider having two factories, both return the same object but with different contracts (interfaces). While in a domain sense it makes sense to have to objects, implementation wise it could be the same. Especially if you have a singleton and inheritance is for some reason not a practical option.

    Keep in mind, I'm not trying to justify the code at hand, just pointing out that something like this is per-se actually a good practice in some cases.

  • (nodebb)

    self is the Python equivalent of this in other languages, and it has to be passed as a parameter because Python is weird

    Strictly, no. You have to declare your (member) function as receiving self, but you don't have to explicitly pass it to the function. Python takes care of that, just like C++ takes care of populating this with the right value.

  • Smithers (unregistered)

    This looks potentially reasonable to me due to Python's duck-typing. If all objects which have an associated request define a request property, it can be convenient for the request object to also have that property pointing to itself.

    A common example of the same concept is iterators: all containers have an __iter__(self) method that returns an iterator over that container. Some functions take a parameter which is either a container or iterator (more generally, an "iterable") to iterate over. The implementation of such functions does not need to distinguish iterators (which it can use directly) from containers (which it has to get an iterator for) because iterators also define __iter__(self) as... return self.

    If any C++ers in the audience need further examples, look at std::ostream_iterator's * and ++ operators which simply return this in order to be useable the same as any other OutputIterator.

  • (nodebb)

    The fact that there are some comments explaining how this may be a non-WTF in Python process that Python itself is TRWTF.

    Addendum 2022-01-25 07:30: Proves not process

  • (nodebb)

    Of course TRWTF are Python developers justifying this non-sense as a totally reasonable way to program. After an inconvenient run-in with the Python package system insanity, I'm fully convinced that I will still see Python surpass PHP in terms of WTF quality and quantity.

  • attentive reader (unregistered)

    TRWTF here is the editor just ignoring the @property decorator. So far my assumption was that the posted code is actually being read with understanding, but as a property this is much less of a WTF than a method would be, IMHO.

  • Chatogaster (unregistered)

    This article should be surrounded by a try-catch Out-Of-Context error.Assuming that the name "request" only got introduced when composing it, the original function name might be sth. like "getMaximum" (aggregator), "getReadableVersion" (weakener) or "getIterator" (fixpoint-ish). Using this technique to merge domains can make a lot of sense.

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered)

    It's like the Ticketmaster "convenience" fees: convenient for them, not for you.

  • Naomi (unregistered) in reply to Mr. TA

    This is a no-op implementation of a method to comply with some interface. There's absolutely nothing unusual about that in any object-oriented language.

  • a robot (unregistered) in reply to tjahns

    I think a good metric of the legibility of a programming language is how deep you can get into it before encountering keywords/functions/symbols starting with an underscore (or worse still, double underscore). That rates python only just above C++

  • Hal (unregistered) in reply to tjahns

    Oh that ship has sailed. If someone asked me take over their amateur PHP project or there amateur Python project - I'd take the PHP any time.

    PHP project - let's give users enough rope to hang themselves Python project - hey now that we have added enough rope to hang yourself what if we weave in some razor blades?

  • Naomi (unregistered) in reply to a robot

    I think a good metric of the legibility of a programming language is how deep you can get into it before encountering keywords/functions/symbols that use Hungarian notation (or worse still, a variant of Hungarian notation). That rates C# only just above C.

    /s

  • (nodebb) in reply to Mr. TA

    The attentive reader will note that I was very careful to avoid passing judgement on the desirability of the code in the article. There are probably reasons for this, although frankly it's hard to imagine any of them being good reasons, especially given the contents of the doc string.

  • (nodebb) in reply to Naomi

    It said "just for convenience", not "to implement an interface", there is no evidence whatsoever to indicate there are any interfaces involved. Furthermore, even if there was a scenario like what you described, which I encountered maybe once in about 20 years, it would be a method named something like "GetXXXX", not "request".

  • (nodebb) in reply to Naomi

    That is a very misinformed statement. Nowhere in .NET BCL nor C# best language practices are any instructions or even hints to use Hungarian notation. In fact, it's explicitly discouraged. To the extent that C# code exists written with Hungarian notation, it's much more often developers who came from languages like C and C++ and brought their habits with them.

  • (nodebb)

    I have done things similar to this in C++ and C# when writing a class hierarchy, where I can not make the base class abstract/MustInherit.

    MyClass *MyClass::request(int a)  // Child class should create their own version
    {
        return this;
    }
    
  • Sole Purpose Of Visit (unregistered) in reply to Steve_The_Cynic

    I'd go with that analysis. The fact that the method has a "@property" decorator suggests that there's some actual reason for its existence (or perhaps was in the dim distant past).

    I've tried to conceive of a good reason to use that decorator for a getter/setter, even in some weird form of an abstract factory, or perhaps for purposes of test injection, and tbh I can't think of one. But in and of itself, it's not entirely silly.

    Not entirely sure how Remy thinks that Python, pre-OO, could manage without passing the class object to methods. After all, it's not a compiled language, and any library that is pre version 3.0 is going to be hard-pressed to do without an object reference. Think, for example, C# monkey patches (aka extension methods). Precisely the same, except that C# is ever so much more verbose and insists on adding "this."

  • Randal L. Schwartz (google)

    In Smalltalk, the shortest method in the entire original 1980 release image was "yourself". The default return value for a method was "self", so the method consisted only of comments. And its use was mostly in cascades! A cascade send returned the result of the send. But typically, you wanted the object that the cascades were being sent to, and used yourself to get that.

    Dart got cascades right.

  • Airdrik (unregistered)

    Coming with a background in python (that is I've been using python in the background for years), I'd agree that this smells like what others have described as being the python equivalent of returning something that implements a specific (duck-typed, so not explicitly defined) interface "for convenience". Without more context, the only wtf here is the docstring which should describe or refer to the documentation on the general pattern/protocol this adheres to (e.g. method foo in package bar expects objects passed in to have a 'request' property that returns an object with method baz ...).

  • (nodebb)

    Fortunately, instead of using thing, with this code you can work with thing.request or thing.request.request or even thing.request.request.request.

  • Sole Purpose Of Visit (unregistered) in reply to dkf

    Cheeseburger cheeseburger cheeseburger ....

  • Sole Purpose Of Visit (unregistered) in reply to Randal L. Schwartz

    That's actually true as well. Perhaps this is just an attempt at fluid programming (which I think corresponds to your cascades). It's not necessarily a good Pythonic way of doing that, which would be more like:

    def request(self, **kwargs)
         ''' Do something with kwargs if they exist
         return self
    

    But, on the other hand, it's not that far off.

  • Argle (unregistered) in reply to Hal

    I haven't had to take over someone's Python project, but I have had to take over PHP. Given a choice between doing that again or playing Russian Roulette, I'm going with the latter. Rube Goldberg machines are as simple as a wedge compared to what I've seen out of PHP code.

  • (nodebb) in reply to Sole Purpose Of Visit

    Buffalo cheeseburger buffalo cheeseburger buffalo cheeseburger...

  • Sole Purpose Of Visit (unregistered) in reply to Argle

    I applaud your effort to take over PHP.

    Someone has to do it. As soon as possible. May it die in a fiery hell.

  • Much Ado (unregistered)

    Super short post, super long comments. The long and short of it is the code is entirely unnecessary. At best, it offers a false sense of security, because while you can say: x = obj.request , you can't also say: obj.request = x, but you could say: obj = x, hence the false sense of security/immutability. It's just a wrong/wasteful use of the @property decorator.

  • (nodebb) in reply to Mr. TA

    "to use Hungarian notation" but naming all your identifiers as types of Paprika can be quite satisfying (especially when one has just worked through a meal time without a break)

  • Chris (unregistered)

    Another possibility is that this is the result of some massive refactoring. The "convenience" was to leave this method, which used to do something, rather than fixing countless calls to request() that exist throughout the codebase.

  • mc (unregistered)

    That's actually true as well.

    http://silvoguard.com/index.html Vitis

  • markm (unregistered) in reply to Chris

    Maybe it is just a dummy method replacing a method that once did something without hunting down and changing every call. But the comment should say that, rather than be completely uninformative.

  • Anonymous (unregistered)

    This has the same mouth-feel as C# and C++ code adding both getters and setters for plain old fields that could just be made public. (I know, I know, "what if it's not that simple"...but 90% of the time, it really is.)

  • TrayKnots (unregistered)
    Comment held for moderation.
  • sai (unregistered)
    Comment held for moderation.

Leave a comment on “Convenience”

Log In or post as a guest

Replying to comment #:

« Return to Article