Hacker News new | past | comments | ask | show | jobs | submit login

And yet, the “nonsense” you see is the object paradigm I love the best out of any language I’ve ever used. It’s what keeps me on perl instead of moving on to other more trendy (and restricted) languages.



You can do everything on that page in Python or Ruby without issue.


I didn't say you couldn't, just that the 'nonsense' is actually quite nice to use in practice.

Lets play Rosetta Code for lazy attributes:

  package Something;
  use Moo;
  has hostname => ( is => 'lazy' );
  sub _build_hostname { chomp(my $x= `hostname -f`); $x }
How would those look in Python or Ruby?

Meanwhile there are many things not on that page which Perl can do and Python and Ruby can't. (most related to taboo runtime changes of global state which are not recommended, but come in very handy when debugging)


> How would those look in Python or Ruby?

   class Something:

      @cached_property
      def hostname(self):
          return socket.gethostname()
I guess, kind of hard to tell what your code does because it is honestly indirect nonsense where you need to know details about some specific library that implements some specific form of objects written in a language that is not exactly well regarded for it's legibility. Meanwhile the code above is clearly readable by anyone with even a modicum of programming experience.

There's also nothing on that page that I can see which Ruby and Python couldn't do. Both are exceptionally good at taboo runtime changes of global state.


Interesting, I hadn't seen @cached_property before. I was expecting you to have to muck around with __getattr__. The lazy attribute in Perl is simply one whose constructed value is deferred until the first time it is used.

For an example of taboo runtime changes, suppose you have one module which operates on a tree of data, like converting to JSON, and another type of object within that tree which does not have a built-in serialization to JSON, like DateTime. (there is really no way to universally serialize a DateTime to JSON because JSON only supports strings arrays and objects, and representation of dates will be application-specific). Perl lets you temporarily inject a method into a class for the duration of a scope, in this case the TO_JSON method which the JSON module looks for:

  sub export_as_json($data) {
    local *DateTime::TO_JSON= sub($date) { $date->ymd };
    JSON->new->convert_blessed->encode($data);
  }
After that scope, the DateTime package is restored to normal, without a TO_JSON method. How would Python solve this problem?


So firstly, it's not up to an object to know how it should be serialized to JSON. It's up to the serializer, and that can be trivially done with the `default` argument:

    def encode(obj):
        if isinstance(obj, datetime.datetime):
            return obj.isoformat()
        raise ValueError()

    json.dumps(..., default=encode)

In Python your code above can usually be done with:

   date = datetime.date.today()
   date.foo = lambda self: print("hello!")
   date.foo()
And this will work on any object that's not defined in C (which unfortunately datetime objects are):

   class Omg: pass

   Omg.foo = 123
   print(Omg.foo)
If you wanted that reverted after a block is finished, you'd use a with statement:

   with patch(date, "foo", some_value):
      date.foo()
There is rarely a need for this outside of tests though.

More generally, you can modify any non-c Python object in any way you want. Nothing is private or protected.

If you're thinking that Perl is special because it has reflection and a dynamic object model, or lazy properties, you've been asleep for quite a while. These have been table stakes for a very long time.


Maybe so. for some reason I thought Python made it hard to modify a class after declaration. I might be thinking of PHP, or maybe I tested something on a C-backed object without realizing.

For what it's worth, Perl lets you freely mix C methods with pure-perl methods in the same object. I also don't think Python has an equivalent for Inline::C

https://metacpan.org/pod/Inline

Getting back to the Moo topic though, you seem to hate the idea of reading user-module documentation to use an object system, but I see that as one of Perl's strengths. Perl's native object system is nothing more than data elements (usually hashrefs, aka dicts) "blessed" with a method table, and the method tables are nothing more than a dict of methods and variables. And you can use user-written modules to generate those packages, and create whatever syntax you like with the user-written modules without depending on core perl to add features. Reading the @cached_property Stackoverflow pages, it sounds like the way to implement this has changed several times over the past decade of Python versions. Moo works as-is on all perls since 5.8, released in 2002.

The ability to take some basic mechanics and build on top of that is what I like. There are dozens of object systems available in Perl because people were free to experiment. Moose was the first one that gained a lot of traction because it solved a lot of common needs. Moo gained a lot of traction for solving most of the same problems while being much lighter weight. I don't think it's any worse to read the manual for Moo than to read the manual for the decorators that Python provides.


There are quite a few packages you can use to build functions in C that operate with Python. Cython is probably the most popular.

Under the hood Python objects are very similar. Classes are mostly just hashmaps (obj.__dict__) and you can easily build something similar to moo in Python. In fact you’d just need some code to convert a module to a class, which is pretty trivial as they are very similar things.

Except you wouldn’t, because it’s madness. The closest you need to come to that is using metaclasses to build some kind of DSL, particularly common in ORMs.

I’ve got nothing against Perl, really, I’m against arguments that say “this language is wonderful because it can do X”, where X is something:

1. Every other language of that type has

2. Every other language does better

Yes, it’s cool you can build your own object model in a package. No, that’s not unique to Perl (Ruby does this more than Python). Yes, it’s a shame you have to.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: