3 ms·
> 1. Code is loaded automatically and globally. I’ve had weird bugs caused by someone creating a function with the same name in a completely different file. Ru
by titusjohnson 2y ago
> 1. Code is loaded automatically and globally. I’ve had weird bugs caused by someone creating a function with the same name in a completely different file.
Ruby doesn't have functions. It only has Objects, and methods on those Objects. Generally you won't run into method nuking because generally there's no need to define the same class in different files.
Yes, you can overwrite method definitions on objects, you can even do that dynamically at runtime. Yes, it's a shotgun. No, it's not wrong, it's just another tool in your toolbelt.
> 2. The module system is strange. Why do my file names and class names need to match? Why can’t i just import the files i want like other languages?
You can require whatever you want, named whatever you want. Rails only looks like magic in this regard because it's coded around conventions so that it can abstract away all that boilerplate. Somewhere before you try instantiate MyController, it was require'd into the project for you utilizing those basic language features. `config/application.rb` is a good reading point to start exploring how this works.
A tremendious amount of logic in Rails is derived from how you name things. Don't fight this system, learn it. Fighting it will only be pain and agony, and I promise you there is a reason for why it works the way it does.
There is absolutly nothing stopping you from calling `require 'my_module'` to bring "BobsGreatestModuleEver" into context. You can missmatch all you want. I have no idea _why_ you would want to do that, seems like a bad precident, but go wild. Ruby works this way like any other language.
> 3. Includes (aka mixins) are a bad idea. See below.
> 4. Many of the language features are designed to hide how code works. Quite often i wonder to myself “where does this variable/function come from?” #1 is also a good example of this.
Includes/Mixins are designed to encapsulate shared functionality. Like any effective shotgun if you shoot your feet off you'll be hurting, so don't shoot your feet.
Use your console! If you've got a class with a method and you have no f'n idea where it's defined, just ask it to tell you.
irb(main):002:0> MyWeirdClass.new.method(:search).source_location
=> ["/app/helpers/weird_stuff/search_methods.rb", 4]
> 5. Coming from a typed language, the lack of types makes me feel naked and more prone to screw something up.
Eh, I think this is one of those tech religious war topics. I've wrangled a lot of typescript and I cannot say that having types have made me feel protected in any way. If anything, TS in particular, it's felt like just _more code_, and I'm a fan of not having any more code that can be helped.
That aside, the Ruby way is Duck typing. If your code is in danger of receiving arbitrary properties, it's very straightforward to protect that code by just inspecting the properties. If it walks like a duck and quacks like a duck, it's probably a duck.
def dangerous_method(arbitrary_thing)
return unless arbitrary_thing.is_a? KnownThing
raise UnsupportedPropertyError unless arbitrary_thing.respond_to? :each
arbitrary_thing.map { |d| ... }
end
> 6. The strange and elitist opinions of ruby fanboys. Sorry but code terseness is not a panacea and “unless” is terrible. It seems like code readability and understandability are less important to this crowd.
Ruby is _all about_ code readability and developer experience. `return unless some_condition?` is gods greatest gift to programming and I will die on that hill.
It can go to an extreme. Like every language you will meet your code golfers who want to take things way, way too far, but that's not unique to Ruby. That's just a people thing. During PR review it's not abnormal for me to ask for terse code to be expanded into a longer form simply for readability.
- CooCooCaCha 2y agoTo each their own, but frankly your assertions sound like nonsense to me. > Ruby doesn't have functions. It only has Objects, and methods on those Objects. Generally you won't run into method nuking because generally there's no need to define the same class in different files. I was writing a rake task and all I did was write a function above the rake task definition. That function was loaded globally and conflicted with another function. If it’s in a rake file then what object is it a part of? This goes back to my main issue about how you don’t know where shit comes from in ruby and there’s too much implicit magic. > Rails only looks like magic in this regard because it's coded around conventions so that it can abstract away all that boilerplate This is what I’m talking about. What you call “abstract away all the boilerplate” I call magical bullshit that makes code confusing. > Includes/Mixins are designed to encapsulate shared functionality. Like any effective shotgun if you shoot your feet off you'll be hurting, so don't shoot your feet. Classes already do that. I’d much rather create an instance of a helper object than magically inject methods into my class. It makes the code more explicit and discoverable too. > I've wrangled a lot of typescript and I cannot say that having types have made me feel protected in any way. That’s strange because types tell you what a thing is and helps you find where it comes from. It offers protection if you use the type system but to each their own. > `return unless some_condition?` is gods greatest gift to programming and I will die on that hill. No, just no. `return if !some_condition?` is far more readable, especially if you have other lines that use `if`. Consistency makes code more understandable. And using `if` everywhere makes it so I don’t have to invert things in my head. > Like every language you will meet your code golfers I’ve worked with a lot of programming languages and ruby is particularly bad. Lots of people jerking themselves off about how short their functions are and you don’t see that in other communities as much.
- gls2ro 2y ago> return if !some_condition?` is far more readable Maybe it is easier to understand the condition or the boolean logic. I could agree with that. But readable? No. It is very easy to miss the `!` when reading multiple lines of code. While missing `unless` it way hardwer. Compare: return if organisation_exists? return if team_exists? return if !user_exists? return if project_exists? with: return if organisation_exists? return if team_exists? return unless user_exists? return if project_exists? Where can you see quicker that it will exit when the user does not exists? For me I need to read twice the lines that only have `if` and I can pick at the first read the `unless`. Not saying you should use `unless` but it is a keyword, like any other keyword that you learn when you learn a new language. We should not confuse lack of familiarity with readability.