7 ms·
What I didn't know about Ruby Classes
- echelon 6y agoRuby's flexibility makes it great for going fast and hacking things, but oh my god can it lead to monolithic spaghetti. Magical eager backfills, mysterious action at a distance method_missing dispatch, crazy class hierarchies and transclusion, endpoints with reflective behavior, nonsensical tests with horrific abuse of rspec, ... I've spent engineering years tearing down Ruby crud others have built, and it's led me to have a distaste for the language like no other.
- nerdwaller 6y agoWhat’s crazy to me is that despite much of this and my general dislike of ruby, I still often reach for rails to get an idea up and out. For my uses I’d rather just test something out and either let it burn down quickly or pay the price eventually to fix it (an old colleague called this a “champagne problem”). I’ve only had to pay the price a few times, which probably made each sequential one easier to avoid some parts. Rails is still a phenomenal framework to use, again something I somewhat begrudgingly admit.
- anonunivgrad 6y agoIt is a lovely language to use but it provides a few footguns too many. The main problem is that the community suffers from bad taste.
- deleted 6y ago[deleted]
- briandear 6y agoThe community is the reason Ruby is amazing. And Matz is one of the nicest guys you’ll ever meet. So genius, yet so humble.
- anonunivgrad 6y agoThe language and standard library are great. I mean that there's a tendency in the third-party libraries to abuse the features of the language for the sake of cute syntax and in the process create a difficult to understand beast where a more straightforward library would do.
- rantwasp 6y agowith great power comes great responsibility. ruby is amazing and once you get past your keanu stage and learn some of its most common pitfalls it's insanely good. it's one of the few programming languages that brings me joy when i use it. also as a side note: if you believe rails==ruby you are limiting yourself. ruby is so much more than rails
- brundolf 6y agoIt's interesting, there seem to be two primary camps when people talk about technologies that "bring them joy". One camp feels this way about maximally-dynamic environments like Lisp and Ruby, which presumably provide "the highest bandwidth" when it comes to translating ideas into code. Whereas for me and others, it's the exact opposite: these languages create nothing but anxiety. Joyful programming, for me, is programming where I can feel confident and peaceful knowing that every possible contingency of a given piece of code has been either accounted-for or prevented. Knowing that I'm not going to be blindsided by anything, being able to narrow my focus to the problem at hand instead of being overwhelmed with the infinite number of things that could go wrong. I wonder what causes such a divergence in mindset
- rantwasp 6y agoi think safety (perceived or real) is different from joy. I also think it’s really hard to enjoy something repetitive and super verbose.
- herbst 6y agoI love creating nearly everything with rails, however i agree picking and cleaning an foreign codebase has always been a pain when i didnt know the team/dev follows a very similar pattern
- pmontra 6y agoYes, some developers like to be needlessly clever and do in Ruby things that they would never do in PHP or Java. I also lost time deciphering some clever metaprogramming. It is more about the developer than the language though. I go with simple solutions no matter which language I use. I worked on some old code of mine last week (it was Python) and I couldn't understand it immediately. I fixed a problem and I'll rewrite part of it this week to make it clear what it does. It will also lower the chances of bugs.
- Lammy 6y ago> Include and Extend your Classes And — since Ruby 2.0 — Module#prepend, which places the prepended Module ahead of the caller in the ancestor chain https://ruby-doc.org/core/Module.html#method-i-prepend https://ruby-doc.org/core/Module.html#method-i-prepend
- amarshall 6y agoWhich is a much nicer alternative to `alias_method_chain` and similar for monkey-patching or enhancing an existing method in a class as it makes more clear the existence and origin of the patch.
- anonunivgrad 6y agoThere's also eigenclasses to further complicate the object model.
- JadeNB 6y agoWhat’s an eigenclass?
- marcandre 6y agoIn Ruby they are called "singleton classes", but the actual technical term is metaclass: https://en.wikipedia.org/wiki/Metaclass https://en.wikipedia.org/wiki/Metaclass (check the Ruby entry)
- masklinn 6y ago> the actual technical term is metaclass Hard disagree. metaclass normally is the class of a class (aka `Class` in ruby), and is used to work manipulate classes. In Ruby, a metaclass is instead an implicit per-object class.
- Lammy 6y agoIt's like a "shadow class" that's unique to an instance of something. No written description of this concept ever really 'clicked' for me, personally, so maybe an example will help. Here's a class with a single method `:hello` that will simultaneously increment a counter on its class and on its singleton_class/eigenclass/metaclass: irb:1* my_class = Class.new do irb:2* def hello irb:2* "I've counted #{self.class.instance_variable_set(:@count, (self.class.instance_variable_get(:@count) || 0) + 1)} of #{self.class}… " + irb:2* "but only #{self.singleton_class.instance_variable_set(:@count, (self.singleton_class.instance_variable_get(:@count) || 0) + 1)} of #{self.singleton_class}!" irb:1* end irb:0> end irb:0> foo = my_class.new irb:0> bar = my_class.new Then if we send :hello a few times to each instance you can see how it behaves: irb:0> foo.hello => "I've counted 1 of #<Class:0x0000561efb9d8238>… but only 1 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!" irb:0> bar.hello => "I've counted 2 of #<Class:0x0000561efb9d8238>… but only 1 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!" irb:0> foo.hello => "I've counted 3 of #<Class:0x0000561efb9d8238>… but only 2 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!" irb:0> bar.hello => "I've counted 4 of #<Class:0x0000561efb9d8238>… but only 2 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!" irb:0> foo.hello => "I've counted 5 of #<Class:0x0000561efb9d8238>… but only 3 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!" irb:0> foo.hello => "I've counted 6 of #<Class:0x0000561efb9d8238>… but only 4 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!" irb:0> foo.hello => "I've counted 7 of #<Class:0x0000561efb9d8238>… but only 5 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efbaa8488>>!" irb:0> bar.hello => "I've counted 8 of #<Class:0x0000561efb9d8238>… but only 3 of #<Class:#<#<Class:0x0000561efb9d8238>:0x0000561efb9d7040>>!" For a real-world example of how this can be useful, I use this pattern in my Jekyll multimedia toolbox to handle the specifics of any certain type of media file (e.g. images, videos, audio, etc). I defined separate Modules for separate media_type handling, a single instance will detect the media_type of its associated file (from the file extension or filemagic), then the instance will differentiate itself by Module#prepend-ing the media_type-specific Module to the instance's `singleton_class`. Then the next instance for the next possible-different-type media file has a clean undifferentiated base to start from and the process can repeat: https://github.com/okeeblow/DistorteD/blob/master/DistorteD-Core/lib/distorted/invoker.rb#L71~L73 https://github.com/okeeblow/DistorteD/blob/master/DistorteD-...
- baron816 6y agoI don’t think I really understood Ruby classes until I learned JavaScript (which didn’t really have classes at the time, and are still pretty different). The mental model that developed for me was that classes are basically fancy functions that create objects.
- riffraff 6y ago> The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures." > Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress. On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened. http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/m...
- QuesnayJr 6y agoi recognize this is a parody of a Zen koan, but I swear to God, it is completely true.
- dragonwriter 6y ago> Classes are constants No, classes are objects. The class declaration syntax assigns the class it creates to the constant given as the name, but it's quite possible to create a class without assigning it to a constant (e.g., via Class.new).
- drosan 6y agoNice paywalled article huh
- burlesona 6y agoI love watching people go deep on Ruby and start to understand how it works under the hood. It’s a beautiful and very powerful language. I will say one thing, though. When you learn how to use all of the dynamic dispatch, meta-programming etc. it can sound like fun to find places to do this stuff in prod. I think it’s better to recognize that all of Ruby exists at runtime, all the time. A lot of the really nifty stuff in Ruby is best thought of as debugging and testing tools. Some parts may be appropriate for framework or library code, but only in very specific situations. Production code should normally be very vanilla and use only the core of the language. It’s true that most other languages don’t offer you this power, and if you don’t have it you can’t abuse it. And that can be a good thing too. Ruby is a language full of power tools and very sharp knives. It trusts you to make your own decisions with that power, and doesn’t protect you from yourself. When you understand that, you can approach it with care and have a uniquely wonderful programming experience.