6 ms·
For me, its the explicitness in Python that is killer. I can see a name and match that to an import and match that to a package. Grabbing a function pointer w
by epage 5y ago
For me, its the explicitness in Python that is killer. I can see a name and match that to an import and match that to a package. Grabbing a function pointer works exactly as I would expect.
Stealing from Krister Stendahl's laws for religious discourse, Ruby's composable iteration is one area I have holy envy, particularly after I got used to it in Rust. I've used Python's generators many times just to have to switch to an explicit for loop. Things are generally better with a composable iteration model but occasionally I find myself switching to explicit loops in Rust.
Unlike Ruby, Rust does pull-iteration like Python, though there are experiments with Ruby-style push-iteration [0] [1].
[0] https://github.com/AndWass/pushgen https://github.com/AndWass/pushgen
[1] https://epage.github.io/blog/2021/07/pushgen-experiment/ https://epage.github.io/blog/2021/07/pushgen-experiment/
- qsort 5y agoI agree. I'm not the biggest Python fan myself and would not recommend it for large projects, but I use it a lot both at work and personally for scripting/small stuff. It feels dumb, but I like dumb for those use cases.
- rgoulter 5y ago> I can see a name and match that to an import and match that to a package. I like this too, but... I don't find dynamic languages to be very explicit. Given that Python is a dynamic language, I only going to know what I can do with (or what is true about) the arguments to some function if I have worked with the codebase previously (or have sufficiently good documentation, and unit test coverage).
- horsawlarway 5y agoAt least with an explicit import you have something to search for. I have often spent several minutes trying to find a definition for a ruby method/modules/class only to finally have to run it and dump the file location manually with `source_location` to find out it's really a 3rd party gem added to the project. Admittedly, Rails makes this much worse.
- rgoulter 5y agoLet alone other 'magical' techniques Ruby affords, e.g. you can re-open a class to monkey-patch more methods in; or even define method_missing so that the methods an object has are dynamic. Some very neat stuff.
- efxhoy 5y ago> I can see a name and match that to an import and match that to a package. I miss this so much. I'm a python dev now working on a big Rails monolith. Where does all this stuff come from?
- joelbluminator 5y agoAre you using a good IDE? With Rubymine (which indexes all of your gems) this is a much less big a deal.
- handrous 5y agoOnboarding to all but the most perfectly-written-and-maintained Rails codebase is pure hell, for exactly that reason. I've done lots of Rails in the past, but sworn it off after enough such experiences. [EDIT] Which sucks, because I really like Ruby.
- Lio 5y agoIf you ever wonder where something comes from and you can't get your editor/IDE to tell you, you can always try asking the runtime. Drop a debugger statement in above the code in question, then at the prompt turn the method into a Method object using something like: bar_method = foo.method(:bar) and then bar_method.source_location Once you have a Method object you can pass it around as a stand alone function, rebind it or call too. #source_location only works for methods defined in ruby itself i.e. not C or Java but it's still a handy tool on big ruby projects. Most of the time I just use ctags to navigate new codebases but we also have things like Solargraph via LSP too.
- nitrogen 5y agoDrop a debugger statement in above the code in question If you're using Pry as your REPL, you can use Pry's ls and show-source commands to get more of the info you want at once, with less typing. It's basically calling the Ruby introspection methods for you. ls foo show-source -d foo.bar
- vidarh 5y ago
- softwaredoug 5y agoAuthor here - I agree on explicitness, it can be a bit maddening to trace where a symbol comes from in Ruby. Though a good IDE helps.
- lamontcg 5y agohttps://tenderlovemaking.com/2016/02/05/i-am-a-puts-debuggerer.html https://tenderlovemaking.com/2016/02/05/i-am-a-puts-debugger...
- nitrogen 5y ago> I think it’s important to say that when you’re debugging anything goes. I mean anything. Global variables, redefining methods, adding conditionals, manipulating the load path, monkey patching, printing the call stack, anything. This is the thing that keeps me coming back to Ruby. The core philosophies of the people who influence Ruby just align so well with my own. [Back in 2008ish I had a choice to learn Ruby or Python, after working with languages including C and Java. I started with Python, but switched to Ruby because Python launched slower and had no native Integer type (important for old ARM CPUs of the era with no FPU), but it's Ruby's philosophy and potential for poetic (but readable!) flow that make it stick now over a decade later]
- cutler 5y agoYes, I think only Clojure surpasses the level of flow you can get with Ruby. Elixir also comes close.
- qudat 5y ago> I can see a name and match that to an import and match that to a package. Grabbing a function pointer works exactly as I would expect. Autoloading is one of the worst features ever introduced into a language/framework. https://erock.io/2021/11/01/on-autoloading.html https://erock.io/2021/11/01/on-autoloading.html
- friedman23 5y agoAh yes, now I remember why I stopped learning ruby and was generally disgusted with the language. Along with the standard library having numerous ways to do the same thing and the general use of monkey patching (and the ruby users actually thinking monkey patching is good)
- pas 5y agoI have no problem with PHP autolading, or TS dependency injection (as seen in Angular, NestJS, TSed), or even in Scala (Play! framework via Guice). Because it's not magic (since you need to import the types you know what you are getting, for PHP there's the autoload.php generated by Composer, for TS everything is in the node_modules and in the lockfile, and for both Scala and TS the compiler checks things too. Of course in TS there are sometimes problems for non-native [ie. JS + .d.ts] libs, when the typing becomes outdated). But in Python the amount of magic shit one had to do to get things loaded in a sane manner was always somehow a serious burden. .. but in Ruby (Rails). Well, yeah, all you have is a lockfile, and nothing else. No imports, no typing. That gets crazy really fast. :)
- saila 5y agoYou can use DI in Python too--it's an architectural pattern that can be used in any project regardless of language. I've never seen or used autoloading in Python. What would the use case for that be? I guess it could be "convenient" to avoid imports? That seems like a bad idea to me and not very "Pythonic." I'm not sure if this is relevant to your comment, but I've seen people abusing sys.path in Python projects instead of setting up a proper package and installing it. Modern Python package/dependency managers like Poetry make this nicer/easier than the old school setup() approach and they also create lock files.
- Groxx 5y agoWell.... except when the package doesn't match the import path. Then you can get stuck in a merry search for "what the heck is X and why is it not in our lockfile".