9 ms·
> I’ve tried python, but I end up having to deal with the mess of importing modules Without those imports, how will people reading the code find the definition
by Buttons840 5y ago
> I’ve tried python, but I end up having to deal with the mess of importing modules
Without those imports, how will people reading the code find the definitions? How will they track down the source code for all the methods being called?
If the answer is "with an IDE / tools", then can't those same tools be used to solve the "mess of importing modules"? If you're using a good IDE, imports and go-to-definition are both solved problems, no matter what language you're using.
If you're not using an IDE, that's a more interesting situation, and without an IDE I much prefer having the explicit imports so that I at least know where to start digging.
- prescriptivist 5y agoThose are fair points, but I just kind of hold the entire program space in my head. I work on a pretty large and complicated Rails app that does real world things (handle money, deal with people and companies, etc) and it's daunting at first but after a while it's sort of become one big system of objects interacting with other objects in a global objectspace and that's how it exists in my head. I think for people that come to love Ruby it feels more natural to think about a program that way as opposed to thinking about a purely lexical context of a piece of code.
- prescriptivist 5y agoWhich isn't to say lexical scope isn't important in a ruby program -- it's paramount, especially for resolving constants -- it's just that after a while it's not that big of a deal that there is some ambiguity about where things come from. For me it's one of the most intuitive languages I've ever worked with but it requires a sense of intuition that is learned over time, as contradictory as that sounds.
- regularfry 5y agoIt also requires a certain sense of confidence that whoever named that method you're calling gave it a good name. Fortunately (and not, I think, coincidentally) the ruby community has always tended towards good naming being really important.
- valenterry 5y agoI think this is actually a very efficient way of programming. but it doesn't scale in project size and team size. Similar for Lisp. This is why these languages are really good for prototyping, but not as good anymore for big, longterm projects imho. That's also why I don't think it's a great idea to add types etc. to programming languages like python or ruby. They are not made for this and they should focus on what they do well. Use the right tool for the job, don't try to make every tool being able to be used for the same task.
- chrischattin 5y agoThis is just not true. There are several multi-Billion dollar public companies with millions of users and thousands of employees built on Rails. In fact, the philosophy of convention over configuration et all makes Rails MORE scalable and easier to onboard new people than anything else out there that I’ve seen.
- jack_riminton 5y agoI agree, the convention means there are very straight-forwarded places to look for things I recently worked on a Rails project for someone who didn't like to create scaffolds, models or controllers for small things, thinking that it would add to the bloat. But conceptually it makes everything 10x times easier and faster to find and understand
- oblio 5y agoWell, you'd better not check what happened to all those Rails apps when those companies grew. There are soooo many blogs about migrating away from Ruby, adopting Go, Scala, whatever statically typed thing. There's a reason even Ruby is getting a proper static type system.
- wavesplash 5y agoUm, really? Why are unicorns like Shopify or Github are still using Rails if that's the norm?
- sanderjd 5y agoThe often impossibility of finding the definition of the methods I'm calling is the main thing that soured me on Rails. I think a more explicit style is more common nowadays, which is a good thing.
- grncdr 5y agoMaybe you already know it, but I find `something.method(:mystery_method).source_location` points me to the right place more often than not. I only mention it because I have noticed a lot of people work productively in Ruby without leveraging it's dynamic/reflective features[0], but little idioms like the above are absolute lifesavers for me. [0]: A big disadvantage of the above is it's not statically resolvable, so you couldn't really build an IDE go-to-definition with it.
- Lio 5y agoThe two tools I'd recommend for navigating ruby code in addition to #source_location are Solargraph[1] and, my favourite, good 'ol exuberant ctags[2]. Solargraph is an amazing project but ctags is still just so fast and low overhead that it's what I mostly use. ctag support is available for most editors and is built into Vim. You need to first generate a tag file (or have an editor plugin do it for you[3]) and then press Ctrl-] to go to definition. 1. https://solargraph.org/ https://solargraph.org/ 2. http://ctags.sourceforge.net/ http://ctags.sourceforge.net/ 3. https://github.com/tpope/gem-ctags https://github.com/tpope/gem-ctags
- nitrogen 5y agoAnd don't forget the option of just calling into pry at the line in question and typing ls and show-doc. Also ripgrep is incredibly useful for navigating new codebases.
- sanderjd 5y agoYes, grep + debugger / pry were how I solved this when I was still writing lots of Ruby. I find it much more productive to be able to get these answers statically, but I was too strong when I said "impossible"; there's always some way to find the right code, or the VM wouldn't be able to run it :)
- llamataboot 5y agoExplicit programming is more readable, but can result in a lot of boilerplate. "Magical" programming is much more intuitive once you know where the magic comes from but can be maddening to debug. Any framework large enough to be useful starts abstracting away implementation details. I've found that people that gravitate towards Ruby enjoy meta-programming. The running joke is that you're not a Ruby programmer until you've decided that you should write a DSL. Like everything, clever programming has its tradeoffs. These days no one reads the source code of every method they call until something is not working the way they expected it to. Personally, I find the JS ecosystem that absolute worst for this because of the amount of imported code to layer basic functionality on top of the standard library. If you've worked with rails long enough - well at that point things like Devise are probably in your mental model of how they work. Personally I still find the large unbridgeable chasm between Python 2 and 3 to be a large friction point in the ecosystem. But if I worked in Python a smuch as I worked in Ruby, I may find Ruby more troublesome. The simple fact is all languages are getting better. The best tool is not always the one that would be best for the job, sometimes it's just the one you know best. And the tradeoffs we make for ease of programming and abstraction can then turn around and mean we are pushing megabytes of JS over the wire when we don't need to, and now we are trying to solve that with more explicit inclusion and automatic tree-shaking in build pipelines etc. It's all good. Every tool has two edges. I'm much happier to see people continue to engage with this edges are figure out how to make them more effective than to always argue about which edge is sharper.
- horsawlarway 5y agoMagic requires memorization. Memorization is not consistent between teams/team-members. Memorization is also the fastest skillset folks lose if they step away from the language/toolset for a while (it degrades rapidly) Worst of all - The RoR ecosystem (6 versions in) requires memorization about which set of things you need to have memorized for this specific version of the framework. I'll take some boilerplate code EVERY FUCKING TIME. The magic becomes a curse.
- joelbluminator 5y agoWhat framework are you using then? Rails is pretty intuitive and easy...I am biased yes but nothing I saw from Spring or Django made me think they made more sense than Rails. The whole Bean thing is pretty crazy. Django is an over engineerd Rails from what I saw.
- epidemian 5y ago> Without those imports, how will people reading the code find the definitions? How will they track down the source code for all the methods being called? I think in dynamic languages like Ruby and Python, there are two very different cases that we need to distinguish when thinking about this. The first one is global references to modules/classes/functions. For example, in Python you may write: import my_module foo = my_module.Foo(some_arg) So, if you wanted to find the definition of that my_module.Foo() reference, it's easy: go to the definition of my_module and search for the Foo class/function definition. In Ruby, you may see instead something like: require 'my_module' foo = MyModule::Foo.new(some_arg) Which looks very similar to Python, with the difference that the `require` method doesn't assign any local binding, but just executes the file my_module, which in turn will modify the global namespace directly and make `MyModule` available at runtime. The `require 'my_module'` might not even be present on the file that's then using `MyModule`: it might be indirectly required by another module that this file uses. Or, in the case of using Rails or any framework with auto-imports, the file might not have any `require` calls at all! So, how is this resolved? By convention, basically. If you see a reference like `MyModule::Foo` and want to see the definition of that, the convention is that that definition will live under my_module/foo.rb, so you can go to that file with some confidence that you'll find the the code for that class there. So, if the convention is strong, and people follow it, this is basically a non-issue, and the go-to-definition can be done as easily as in Python, with or without an intelligent IDE. --- The second case is when you have a dynamic reference to an object/function/whatever, like: def do_something(arg): arg.foobar() In this case, neither Ruby nor Python (or any dynamic language in general) will help you much in trying to find the definition of the `foobar` method, as the type of the argument will only be known at runtime at the moment that this function will be called, and can even vary between calls. There are different ways to make this go-to-definition somewhat more ergonomic than a global search for `def foobar`. But on the language level, i think both Python and Ruby are basically the same in this case: not very helpful. We then compensate by using good naming conventions, type annotations/comments, or using powerful IDEs that analyze the code to make good guesses about who is calling what.