[HN Gopher] To Ruby from Python
       ___________________________________________________________________
        
       To Ruby from Python
        
       Author : mariuz
       Score  : 182 points
       Date   : 2022-07-16 06:51 UTC (16 hours ago)
        
 (HTM) web link (www.ruby-lang.org)
 (TXT) w3m dump (www.ruby-lang.org)
        
       | by_the_bay wrote:
       | One of my biggest complaints about Ruby is that that it's so much
       | harder to drop into a debugger. In python it's as easy as import
       | pdb; pdb.set_trace(), but for ruby (at least the versions on our
       | build systems), you need to figure out how to add the dependency
       | for pry/byebug first which is non trivial.
        
         | tomstuart wrote:
         | A fair complaint, but FYI it's outdated as of Ruby 3.0
         | (released in 2020) which includes the `debug` gem [0]. So in
         | Ruby 3.0 onwards it's as easy as `require 'debug'; debugger`
         | just like you want. Hopefully your build systems will upgrade
         | to a newer Ruby before too long.
         | 
         | [0] https://stdgems.org/debug/
        
       | zem wrote:
       | as someone who has used ruby for years, and more recently got a
       | job working in python, I think the most significant difference
       | between the two languages is how they handle imports.
       | 
       | in python every file is also a module, and all imported symbols
       | are namespaced within that module (unless you deliberately use
       | "import *" to bring them into the current module's namespace). so
       | you can define function foo in module bar and use it via "import
       | bar; foo.bar()".
       | 
       | in ruby, modules/namespaces and files are two entirely orthogonal
       | concepts; you define a module by enclosing code in a "module Foo;
       | ...; end" block, and any file can open up the same module and add
       | stuff to it. when you import a file it adds everything within it
       | to the current global namespace, which makes it really hard to
       | read a piece of ruby code and see where everything within it was
       | defined.
       | 
       | for the most part where ruby and python differ I prefer the ruby
       | way, but I feel like automatically namespaced imports is
       | something python got right, and was a really big miss for ruby.
        
         | ufmace wrote:
         | It's a possible smell in Ruby all right. Ideally, every file
         | has its code in classes or modules that match the file name, so
         | require 'foo' brings in the class Foo and nothing else. But
         | it's possible to do some really ugly hacky stuff, so it more
         | becomes please don't actually do that in a large production
         | codebase.
         | 
         | Python's default of namespacing imports is nicer all right,
         | though I've seen a decent amount of Python code in the wild
         | that has a dozen import * at the top of every file so that grep
         | is the only way to find out where a function is actually
         | defined, just as bad as Ruby.
        
         | choward wrote:
         | Ruby modules and requires effectively just concatenate a bunch
         | of files that have globals in them and have nothing to do with
         | real modules.
        
         | mountainriver wrote:
         | Agree Ruby code is super hard to understand, this seems largely
         | overlooked by the community
        
           | gls2ro wrote:
           | (out of curiosity) What is hard to understand about Ruby?
        
             | bcbrown wrote:
             | Of the languages I've used in anger, Ruby is perhaps my
             | favorite language to write code in. I think Python and Java
             | are both easier to use in a large shared codebase, and one
             | of the biggest reasons is that it's sometimes a lot harder
             | to see where a method is defined in Ruby. Being able to use
             | method_missing to automatically build a wrapper class or
             | shim is super easy and pretty cool, but it can make it much
             | harder to piece things together when debugging.
             | 
             | I worked at a company that had a codebase split fairly
             | evenly between Ruby, Java, and Python. The Ruby stuff was
             | the hardest to understand, and I think it was primarily
             | because of using patterns around dynamically method
             | definitions.
        
             | dolni wrote:
             | One thing that drives me up a wall about Ruby (versus
             | Python) is that function and method calls have basically
             | zero context so you have _no idea_ where a piece of code
             | actually lives without investigating or relying heavily on
             | IDE features.
             | 
             | Call a method on the current object? You just punch in the
             | method name. There's no leading `self.` to indicate you're
             | interacting with this class.
             | 
             | If you require a library, the required code can be
             | literally anything. Namespacing of the classes and
             | functions is optional. Hopefully the library author did
             | something reasonable. And even if they did, that
             | namespacing isn't gonna match your require statement.
             | 
             | Python's explicitness around this stuff is absolutely a
             | breath of fresh air compared to Ruby's wild west approach.
             | 
             | I also gotta say I'm not a fan of the fact that there tend
             | to be one or two method aliases for lots of stuff in the
             | standard library. It makes code easier to write but harder
             | to read. As an example: the Array class has push, append,
             | <<, unshift, prepend, and insert methods. Append is
             | sensible. Do we _really_ also need it to be called push?
             | and do we _really_ also need <<?
             | 
             | Prepending is an uncommon enough operation that
             | "array.insert(0, object)" should have been sufficient.
             | 
             | I understand the intention behind Ruby's design decisions
             | but I personally feel they do programmers a disservice.
             | Writing (or even reviewing) Ruby without a featureful IDE
             | is an absolute chore for projects of any appreciable size.
        
               | gls2ro wrote:
               | First, I do agree that Ruby ecosystem could do some
               | things better and IMO in the last year or so there are
               | some good projects happening in this space.
               | 
               | Second, I cannot refute your arguments. That is because I
               | see them more of a personal preference or somehow
               | expectations based on your programming history (I might
               | be wrong of course as I don't know your programming
               | history). As Ruby feels similar with other programming
               | languages I think some kind of expectations of how things
               | should be kick in. But Ruby has a specific design that is
               | for example focused on "brevity" or "beauty" among
               | multiple other thigs.
               | 
               | I worked so far in the last 15 years in multiple
               | codebases in Ruby: large Rails apps, Sinatra apps but
               | also smaller webapps. In all kind of combinations some of
               | them I built and maintained alone and some of them were
               | built in a team.
               | 
               | This being said, I don't remember a time when we have a
               | big name conflict because we used a couple of gems and
               | they were colliding.
               | 
               | I do remember when some colleagues were over using meta-
               | programming too much or changing default behaviour of
               | stdlib. But this can be fixed with coding guidelines and
               | I take imposing coding guidelines over removing these
               | features from Ruby as sometimes they make more sense than
               | anything else.
               | 
               | Regarding ".self" I don't feel the need to use it. Once I
               | got the call hierarchy I prefer not needing to write
               | "self" where it is not needed.
               | 
               | But also in Ruby everything* is an object thus I feel
               | that self is a bit more powerful so it should be used
               | when when it is really needed like when defining methods
               | and you want to indicate where that method belongs.
               | 
               | Regarding having multiple ways of doing the same stuff in
               | stdlib, here we diverge as I prefer this diversity. I
               | really like that we are multitudes in this community so
               | code can be written in multiple ways, it is for me almost
               | like a form of art when I read some case and I see how
               | expressive can it be and how easy it is to get what it
               | does even if it uses a different std method than I
               | normally use.
               | 
               | I think if you want to get Ruby you should start by
               | thinking that Ruby is a programming language created
               | (IMHO) with the intention to let you express yourself but
               | also make it so that other people should easily
               | understand it.
               | 
               | It also worth reading this beautiful essay by the creator
               | of Ruby: https://www.oreilly.com/library/view/beautiful-
               | code/97805965... (sorry I could not find a direct link
               | unwalled) and from there you will get a glimpse of why
               | Ruby is in a specific way and see if you agree or not
               | with that.
               | 
               | For example regarding your point with no leading self,
               | Matz says in that essay "programs should ideally contain
               | no unnecessary information" thus a lot of what you see in
               | Ruby including having prepend instead of "insert(0,
               | object)" is a manifestation of that.
        
           | atmosx wrote:
           | It can be, more than other languages, but doesn't "have" to
           | be. Complex code is a smell.
        
             | entropie wrote:
             | Meta programming stuff can be very confusing for non native
             | rubyists. Generally thats something one should avoid in
             | shared/production codebases.
        
               | lgreiv wrote:
               | As someone with a bit more of a decade of Ruby
               | experience: meta programming can be very confusing for
               | native rubyists, too. There is a place for it (my
               | personal take would be that this place is usually
               | libraries/gems, e.g. if they need to be flexible to adapt
               | to the consumer's project), but it's usually not code
               | that needs to ,,convey a story" (usually business logic)
               | or needs to be debugged/observed.
        
           | tomc1985 wrote:
           | I have never had this issue, other than with some of its more
           | complicated constructs (like class << self).
           | 
           | And amongst the community, this is not a complaint I hear
           | very often.
           | 
           | I still think of Ruby as the language that maps closest to my
           | thought process when programming.
           | 
           | What is troubling for you?
        
         | lloeki wrote:
         | The tradeoff is that you don't get to have open classes with a
         | module oriented approach.
         | 
         | Shameless plug: toyed with the idea of imports and "packages"
         | in Ruby some time ago. Recent facilities in 3.1 (or 3.2?) could
         | make the implementation even easier.
         | 
         | https://github.com/lloeki/pak
         | 
         | https://github.com/lloeki/ruby-package
         | 
         | IIRC there's an issue somewhere at bugs.ruby-lang.org about
         | that
         | 
         | EDIT: OMG 8 years ago! /me screams
        
           | dragonwriter wrote:
           | > The tradeoff is that you don't get to have open classes
           | with a module oriented approach.
           | 
           | A module oriented approach could still have open classes, and
           | if you did an imported module could still mess with classes
           | in other imported modules (it would just also have to import
           | them.)
           | 
           | In fact, you can set variables in other modules and members
           | (including methods) of other classes this way in Python.
        
           | zem wrote:
           | i like that! it definitely makes things cleaner in terms of
           | being explicit about where everything comes from.
        
         | typeofhuman wrote:
         | > so you can define function foo in module bar and use it via
         | "import bar; foo.bar()".
         | 
         | Wouldn't this be "import bar; bar.foo()"?
        
           | heartbreak wrote:
           | Yes, it looks like OP had a typo.
        
           | 86J8oyZv wrote:
           | In Ruby it's "require" rather than "import." But it would be
           | more like "require bar; foo()".
           | 
           | However, Ruby _does_ have auto-loading conventions. So you
           | could define "module Baz{ module Bar { def foo end; } }" in
           | "baz /bar.rb" from the root of your project. You should then
           | be able to call "Baz::Bar::foo()" from any other file in your
           | project structure without a "require" at all. This is not
           | standard Ruby IIRC, but Rails and other frameworks use it.
        
             | gls2ro wrote:
             | There is a gem that does that used by Rails and multiple
             | other gems:
             | 
             | https://github.com/fxn/zeitwerk
             | 
             | It is pretty easy to set it up in any Ruby project.
        
             | dragonwriter wrote:
             | it would actually be:                 require 'bar'
             | foo
             | 
             | because require is a regular method and the argument is a
             | string (I mean, you could pass _bar_ without quotes if the
             | string was in a variable called _bar_ , but that's not the
             | scenario being discussed.)
             | 
             | > However, Ruby does have auto-loading conventions. So you
             | could define "module Baz{ module Bar { def foo end; } }" in
             | "baz/bar.rb" from the root of your project. You should then
             | be able to call "Baz::Bar::foo()" from any other file in
             | your project structure without a "require" at all. This is
             | not standard Ruby IIRC
             | 
             | autoload is a Kernel method in Ruby core, so it is standard
             | Ruby, but you have to explicitly register a file to be
             | automatically loaded when a particular method is
             | referenced.
             | 
             | Some systems additionally include code that does this for
             | source files based on path.
        
             | khaledh wrote:
             | > You should then be able to call "Baz::Bar::foo()" from
             | any other file in your project structure without a
             | "require" at all.
             | 
             | IMO, this is a downside rather than an upside. It's
             | optimizing for writing rather than reading. This hurts
             | understandability for someone who is not familiar with the
             | code base.
        
               | jonnytran wrote:
               | IMO, Ruby optimizes for reading. You simply cannot write
               | concise code in Python as in Ruby. One reason (of many)
               | is because of all the import statements required in
               | Python. In Ruby, there is often only a single require
               | statement, or maybe none at all, at the top of a file.
               | 
               | The difference is convention over configuration. In Ruby,
               | if you know the convention, then you know exactly where
               | everything is defined without needing to read it. In
               | Python, you must read all those import statements to know
               | where something is coming from, not to mention write them
               | in the first place.
               | 
               | And if you really need to know where something is
               | defined, you simply ask it.                   puts
               | obj.method(:foo).source_location
               | 
               | So IMO, Ruby optimizes for both reading and writing.
        
           | zem wrote:
           | right, that was my mistake
        
       | bamboozled wrote:
       | Forget all of it and use Go :)
        
         | entropie wrote:
         | Probably not a bad advice.
         | 
         | Most of the ruby enthusiasts I know from the old days took a
         | deeper dive into go.
        
           | goatlover wrote:
           | I would think Elixir or Crystal would have been the more
           | natural transistion for Rubyists. Or even Common Lisp. Go's
           | philosophy is very much at odds with Ruby's.
        
         | jonnytran wrote:
         | The only thing I disliked more than moving from Ruby to Python
         | was moving to Go. All the things I love about Ruby are the
         | antithesis of Go.
        
         | x86x87 wrote:
        
       | vault wrote:
       | deleted
        
         | greenpeas wrote:
         | What do you mean?
         | 
         | > When tested for truth, only false and nil evaluate to a false
         | value. Everything else is true (including 0, 0.0, "", and []).
         | 
         | In ruby only `false` and `nil` evaluate to false values. 0, [],
         | "" all evaluate to true when used in `if` statements. In python
         | (just like in C and JS) many things evaluate to false
         | (including 0, 0.0, "", and []).
        
           | vault wrote:
           | Ah sorry I read "Unlike Ruby, in Python" instead of "Unlike
           | Python, in Ruby"
        
       | thih9 wrote:
       | This page is old [1], is there any reason or context regarding
       | why it is interesting now?
       | 
       | [1]: Archived in 2006:
       | https://web.archive.org/web/20060925032432/https://www.ruby-...
        
         | Kwpolska wrote:
         | The page has been slightly changed since then, but it is still
         | quite outdated. Python 3.6 (2016) has formatted strings, and
         | new/old-style classes thing isn't relevant at all since Python
         | 3, but wasn't that much of a deal with Python 2 at the end of
         | its lifetime (~everything was new-style by then).
        
           | sitkack wrote:
           | Ruby is a neat language that I don't know very well. Blocks
           | are nice. The pattern matching in Python 3.10 compels me to
           | stay.
        
             | weaksauce wrote:
             | ruby has some nice pattern matching too
             | https://rubyreferences.github.io/rubyref/language/pattern-
             | ma...
             | 
             | not sure if python has better matching though but the ruby
             | stuff is pretty compelling.
        
       | mahathu wrote:
       | I love Python and use it pretty much anywhere I can, especially
       | as it's ubiquitous in scientific computing. Is there a good
       | reason to switch to Ruby except to try something new?
        
         | linuxftw wrote:
         | As a non-ruby user, from my POV ruby is primarily related to
         | webapps. While it's possible to use it for other types of
         | software, nobody really does, except possibly people that
         | already maintain large codebases of ruby webapps.
        
         | nixpulvis wrote:
         | I would claim that Ruby as a language is much nicer to use,
         | however it has less support for data science and other things
         | which Python is much more well known for. If you ported over
         | some libraries, you might find you like Ruby more in the end.
        
           | doix wrote:
           | My biggest gripe with Ruby is how much syntax is optional and
           | the "accepted" conventions by the community are to leave out
           | a lot of optional syntax.
           | 
           | The worst offender (in my opinion of course) is leaving out
           | of empty parentheses on method calls. It makes it impossible
           | to know if something is a property or a function. The
           | argument is that it doesn't matter if it's a property or a
           | function, but I feel like it makes it very difficult to
           | reason about performance. If I know something is a function,
           | I'll look at the function and see what the performance
           | implications are. Where as if something is a property, I
           | assume it's "free" to access. This doesn't hold when reading
           | Ruby code, and I basically have to look up everything all the
           | time.
           | 
           | Just my opinion as someone that had to switch between
           | python/ruby/perl to maintain tools written during different
           | decades.
        
             | nixpulvis wrote:
             | Always use parens. That's my rule.
        
             | ByteJockey wrote:
             | > but I feel like it makes it very difficult to reason
             | about performance
             | 
             | This seems like a form of premature optimization.
             | 
             | I mean, you're not wrong technically, but if you were
             | exceptionally performance concerned, you probably wouldn't
             | be using ruby.
             | 
             | If you're just regular performance concerned (i.e. you want
             | to stop pathological behavior in the hot loop), you're
             | really only concerned about 1-2% of your code. You wait
             | until it's an issue, run a profiler over your code and
             | optimize the couple of parts that are causing the issue.
        
             | floodedchip wrote:
             | What do you mean by "property or function", though?
             | 
             | There are no properties or functions in my view--only
             | messages. object.message sends message to object, which
             | object may or may respond to.
        
               | dehrmann wrote:
               | It's the same in Python. Methods just happen to be
               | callable properties.
        
       | wodenokoto wrote:
       | > There's only one kind of list container (an Array), and it's
       | mutable.
       | 
       | What are the other kinds of list containers in Python? I only
       | know of `list()`/`[]`, but maybe I just don't realize that some
       | other thing I use is also a list container.
        
         | zbentley wrote:
         | array.array, as another commenter mentioned; numpy.array is
         | popular for performance-oriented code (but not in the stdlib);
         | collections.deque; queue.Queue; tuple; struct (though it's a
         | bit of a pain to make one behave in an array-like way and is
         | usually better to use array.array); heapq; and
         | multiprocessing.shared_memory.ShareableList.
         | 
         | Out in pypi there are many additional esoteric list-like data
         | structures: bitarray is one of my favorites, and there's also
         | awkward-array, cyarray, tinyarray, fixedlist, blist, bigarray,
         | sortedcontainers, and many many more.
        
         | uranusjr wrote:
         | I'm guessing they're implying tuple, it's pretty common to
         | consider that type as "immutable list" (although personally I
         | very much dislike this categorisation)
        
           | masklinn wrote:
           | > although personally I very much dislike this categorisation
           | 
           | It's not a categorisation, it's literally the nature of the
           | thing in Python. And while I agree that it's distasteful the
           | error was in the original introduction.
           | 
           | As things are, python tuples are immutable sequences with all
           | that implies. They are iterable, indexable, sliceable, ...
        
             | baq wrote:
             | Immutability crucially allows for hashability, so you can
             | use (some) tuples as dict keys.
        
         | kevin_thibedeau wrote:
         | array.array
        
       | nixpulvis wrote:
       | > The usual-style comments on the line(s) above things (instead
       | of docstrings below them) are used for generating docs.
       | 
       | This is another thing about Python that I find very unsettling
       | and wrong.
        
       | scotty79 wrote:
       | For me there wasn't ever question of "How?" only "Why?".
       | 
       | One time I landed on Ruby project and I didn't have any trouble
       | fixing bugs and implementing minor functionalities without really
       | learning Ruby only knowing some Python.
        
         | cortesoft wrote:
         | I feel similarly about python. I use ruby all the time, but can
         | do things in Python just fine, especially if I have an existing
         | code base that I am working on.
        
           | scotty79 wrote:
           | Tensorflow? Numpy?
           | 
           | No idea what else might be the reasons to learn Python when
           | you know Ruby.
        
       | mark_l_watson wrote:
       | I loved coding in Ruby. I also wrote a Ruby book for Apress, my
       | last book for a major publisher before starting to self publish
       | on leanpub.com/u/markwatson
       | 
       | Two factors made me leave Ruby behind: I am somewhat known for
       | Common Lisp, and so CL jobs would come my way. Also, in the last
       | 8 years, a huge amount of my work has been in deep learning and
       | Python wins there.
       | 
       | Anyway, Ruby was designed to make programmers happy, and it is a
       | big success at that.
        
         | brudgers wrote:
         | Genuinely curious, would Ruby be your desert-island-with-only-
         | one-language language?
         | 
         | If not, what would your language be?
         | 
         | Of course, you could - at least in theory - take any language
         | and implement some other in it...so I guess maybe there's a
         | question of is it easier to write Lisp in Ruby or Python in
         | Lisp, etc.?
        
           | mark_l_watson wrote:
           | That would be Common Lisp.
        
           | x86x87 wrote:
           | probably you would want C on a desert island. you could write
           | your own ruby or python or anything in it.
        
         | itake wrote:
         | > Anyway, Ruby was designed to make programmers happy, and it
         | is a big success at that.
         | 
         | I switched to golang from ruby and I definitely don't miss the
         | ctrl+f hunts to figure out the source code of functions in ruby
         | programs. its even worse when dynamic programming is used to
         | create 'helper' methods (e.g. `{attribute_name}_changed?`) that
         | you have to read through lines and lines of code to find
         | anything.
        
           | jkogara wrote:
           | I use ctags that are rebuilt in the background on each commit
           | or pull, makes find source code of definitions trivial.
        
           | jshen wrote:
           | I find most things by jumping into pry at a break point and
           | inspecting it. Works really well, but isn't something that's
           | common in other languages so people don't think to do it.
        
           | msbarnett wrote:
           | If anyone very finds themselves hunting around for a method
           | definition like this,
           | method(:blah_changed?).source_location
           | 
           | is your new best friend.
        
         | [deleted]
        
         | Hackbraten wrote:
         | I tried for many years to be happy with Ruby.
         | 
         | Ended up leaving it behind because more often than not, when I
         | revisited a Ruby codebase after a while, Bundler would complain
         | and tell me that I'm supposed to run `bundle install`
         | something, and sure enough, doing just that sent me into a
         | rabbit hole of errors.
        
           | gls2ro wrote:
           | I am sure it will not bring you back :) but in case others
           | might read this and have the same issue the solution is to
           | config bundler to install the gems locally inside a project
           | folder (I usually go for ./vendor/bundle) and the add that to
           | .gitignore
           | 
           | This way if you work with multiple projects each using
           | different Ruby versions and different gem versions you don't
           | keep to keep reinstall the gems whenever you switch the
           | directory.
        
             | jbverschoor wrote:
             | Gems are versioned already, and if you're working with
             | different Ruby versions, your gems are already isolated to
             | that version.
             | 
             | No need to vendor gems..
        
             | jbverschoor wrote:
             | Gems are versioned already, and if you're working with
             | different Ruby versions, your gems are already isolated to
             | that version.
             | 
             | No need to vendor gems.. Vendoring millions and millions of
             | duplicate files is for the node crowd.
        
               | theonething wrote:
               | > Vendoring millions and millions of duplicate files is
               | for the node crowd.
               | 
               | and PHP
        
             | LV123 wrote:
             | "sure enough, doing just that sent me into a rabbit hole of
             | errors"
             | 
             | I did that exact thing in a project last weekend, and ended
             | up spending 5 hours trying to fix the horrible mess that
             | ensued. I only tried doing this in the first place because
             | bundler errored out on installing one of the gems, and I
             | figured a "clean" local setup would fix things.
             | 
             | For some reason the project still wanted to use global
             | gems, and when I tried to delete them to force it to use
             | local gems I broke everything. In the end I just installed
             | RVM with a clean version of Ruby and let it use global
             | gems.
             | 
             | I'm sure I did it wrong, but the errors I got were just
             | insane. I couldn't delete gem X because I had gem Y
             | installed, I couldn't delete gem Y because I DIDN'T have
             | gem Z installed. I couldn't install gem Z to delete Y to
             | delete X because my installed version of gem Q didn't match
             | the version bundler wanted, but I couldn't install a new
             | version of Q because of reasons...
             | 
             | After reinstalling the exact same gems (through RVM instead
             | of the apt-get version of Ruby I had before) things still
             | didn't work, and it took me quite a long time to figure out
             | that the error "your version of [some YAML gem] is wrong"
             | means that you have to add a line of Apache config telling
             | Passenger to use Ruby.
        
               | revscat wrote:
               | > I did that exact thing in a project last weekend, and
               | ended up spending 5 hours trying to fix the horrible mess
               | that ensued.
               | 
               | What gem(s) were giving you issues? I can try and
               | replicate it if you'd like.
        
               | gls2ro wrote:
               | I am sorry for your experience with this.
               | 
               | I am just trying to understand your case. So if you have
               | a Gemfile in your folder and then execute something like
               | bundle config set --local path "vendor/bundle"
               | 
               | Then all gems should be installed in ./vendor/bundle.
               | 
               | I am not sure how Passenger works (as I am mostly using
               | Puma). I am assuming based on what you wrote that the
               | issue was with the gem passenger itself which is used by
               | the Apache config and it is not a library used by your
               | project.
               | 
               | I don't think the issue you encounter is representative
               | to Ruby and it's ecosystem. I think any module loaded to
               | Apache will probably need a way to know how to load some
               | other modules and probably passenger (via Apache config)
               | needs to know where to find the dependencies it has.
               | Passenger is a web-server so it has its own dependencies.
               | 
               | My suggestion was about the dependencies of your own
               | project.
               | 
               | I am usually doing projects with Rails and Sinatra + Puma
               | + Nginx or Apache and in both of them with the setup I
               | shared I did not encountered any problems releasing the
               | project in production with bare metal configuration (via
               | Capistrano for example) or using Docker.
               | 
               | I am not saying that my experience is representative for
               | everything in Ruby ecosystem. I started using Ruby in
               | 2007 with Ruby 1.8 and I do agree that we had some rough
               | years in the ecosystem specially when working on multiple
               | projects simultaneously.
               | 
               | But now, my experience is a breeze.
               | 
               | On a tangent, I have more problems with npm/yarn than
               | with gems. For example I just started to upgrade an old
               | Rails app to Rails 7 and suddenly on my Mac OS a npm
               | package needs some kind of Python version with some
               | libraries that in turn seems to require some other stuff.
               | Even if I am more like a dinosaurs and prefer to run
               | locally all projects (thank maintainers for asdf) for
               | this one I let it go and put it in docker :)
        
               | LV123 wrote:
               | Thanks, I'll give it another try some day and try
               | switching to local gems. I used the exact command you
               | suggest and it didn't work, but I don't remember why.
               | Unfortunately I didn't keep all the logs, so I don't
               | remember exactly what all the errors were, but I think
               | Passenger was the cause of about half of my woes and I'll
               | look into replacing it.
               | 
               | Bundler was pretty damned useless though, I've had a much
               | worse experience with that than I've ever had with yarn,
               | pip or npm. It really shouldn't be necessary to nuke the
               | whole Ruby installation to do a clean install from a
               | Gemfile, and the errors it produces are extremely
               | misleading and unhelpful.
               | 
               | I'm not really a Ruby dev, I just inherited an ancient
               | Rails project and had to make it work (upgrading from
               | Rails 4 to 7 in the process), so the project setup is
               | less than ideal. I'm sure a lot of my problems were self-
               | inflicted ;-)
        
               | gls2ro wrote:
               | Thank you for replying to give more context.
               | 
               | You have some courage to go to a Ruby project and try to
               | upgrade Rails from 4 to 7. I hope it will go as smoothly
               | as possible. Props to you!
               | 
               | I am not sure if it helps and maybe you know these, but
               | just in case here are 3 URLs I keep at hand when I
               | upgrade Rails:
               | 
               | 1. https://railsdiff.org (where it shows diff from
               | sources)
               | 
               | 2. https://www.fastruby.io/blog/tags/upgrades (they have
               | some great articles in cases of some upgrades)
               | 
               | 3. https://guides.rubyonrails.org/v6.1/upgrading_ruby_on_
               | rails.... (there is page for each version just replace
               | v6.1 with the major version that you need)
               | 
               | And also if you have not already started may I suggest
               | you don't go directly from Rails 4 to Rails 7 but just
               | try to go to each major(ish) version:
               | Rails 4.0 -> 4.1.x        Rails 4.1 -> 5.0.x        Rails
               | 5.0 -> 5.1.x        Rails 5.1 -> 5.2.x        Rails 5.2
               | -> 6.0.x        Rails 6.0 -> 6.1.6.1        Rails 6.1 ->
               | 7.0.x
               | 
               | For each version there is an upgrade page. Eg:
               | 
               | - https://guides.rubyonrails.org/v4.1/upgrading_ruby_on_r
               | ails....
               | 
               | - https://guides.rubyonrails.org/v5.0/upgrading_ruby_on_r
               | ails....
               | 
               | - https://guides.rubyonrails.org/v5.1/upgrading_ruby_on_r
               | ails....
               | 
               | You might want to give a try to this gem:
               | https://github.com/fastruby/next_rails. I did not used it
               | so far but I would have a Rails 4 app I will probably try
               | to use it.
        
               | LV123 wrote:
               | Thank you! Those resources would have been incredibly
               | helpful 6 months ago, haha.
               | 
               | It was less courage and more desperation, as the project
               | was running on a server which died before Christmas and
               | we needed it back up before January. The last major
               | change to the project was ~6 years ago and nobody had
               | touched it in ~5 years, so there was nobody around who
               | had the slightest idea how it worked. Props to Rails for
               | just _working_ for that long with practically zero
               | maintenance. In case you 're wondering why we had
               | critical software running on a single server with no
               | maintenance: student organization.
               | 
               | We weren't able to find/install an Ruby installation old
               | enough to run the project, so we decided to just upgrade.
               | It was the brute force approach of "run the project, see
               | what error pops up, google the error, fix the error,
               | repeat". In hindsight, this wasn't a good idea and I
               | could probably have found the right Ruby version with a
               | bit more digging, but it works at least.
               | 
               | It's just a handful of pages with minimal code though, so
               | now that things are less desperate I'm considering just
               | starting from scratch with a clean Rails install and
               | manually recreating them. Just need to deal with the
               | legacy database schema and make some changes to it.
        
           | mpyne wrote:
           | For what it's worth that's also been my experience with some
           | Ruby projects I have. Usually bum-simple Jekyll web sites in
           | response to a dependabot warning.
           | 
           | It's almost always a fight to get going again and it seems so
           | needless. Like just reinstall the gems from scratch if you
           | need to, jeez, this isn't even a CI I don't need the gems to
           | be literally identical to what was here a year ago, I just
           | need "bundle exec jekyll serve" to actually do something...
           | 
           | That all said I still like Ruby as a language, it brings the
           | good stuff over from Perl while being as expressive as Python
           | and pretty damn fast to boot. And I recognize Python also has
           | similar dependency challenges. But this is very irritating.
        
             | entropie wrote:
             | > It's almost always a fight to get going again and it
             | seems so needless
             | 
             | Hm. I do ruby webdev stuff for over a decade now (first
             | ramaze, hanami now) and use a self baked overlay that
             | manages multiple hanami apps and capistrano to deploy them
             | and shares plugins to all the webapps (like a blog
             | component).
             | 
             | I love it. Sure, there were problems with bundler and some
             | with capistrano too but overall its very pleasant for me.
        
           | weaksauce wrote:
           | as an other perspective this happens because you are not
           | pinning the versions correctly. your gemfile should have an
           | explicit version of every major gem you use and the
           | gemfile.lock should have the resolved dependencies already
           | made out and committed. you should also have a particular
           | version of ruby in mind and locked with a .ruby-version file
           | in the project root. This should work flawless in all but the
           | oddest edge cases.
        
           | jspash wrote:
           | Leave a javascript project for more than 2 weeks and you'll
           | get the same thing.
        
           | Taikonerd wrote:
           | If you switched to Python, then you probably traded your
           | `bundle install` errors for `pip install` errors ;-)
        
             | fny wrote:
             | Pip doesn't do dependency resolution either... I spent a
             | day trying to pin down issues migrating a project from
             | pipenv to poetry because poetry did not agree with pipenvs
             | resolution.
        
               | neeleshs wrote:
               | AFAIK, pip does dependency resolution, you can disable it
               | via --no-deps
               | 
               | https://pip.pypa.io/en/stable/topics/dependency-
               | resolution/
        
               | fny wrote:
               | Excuse me I should have said conflict resolution.
        
       | [deleted]
        
       | hawkeyedan wrote:
       | Arguments about the "superiority" of Python vs Ruby always sound
       | a bit like arguments about the "superiority" of Italian vs
       | Spanish. If you squint a bit they're basically the same.
       | 
       | (By that simile, Lisp would be Sanskrit?)
        
         | thebigspacefuck wrote:
         | True, but 85 million Italian speakers vs 500 million Spanish
         | speakers so that tells you something. Sure the Roman Empire was
         | big back in the day but the time has passed.
        
       | ptx wrote:
       | > _You can read docs on the command line (with the ri command
       | instead of pydoc)._
       | 
       | I've been using Python for a long time, but somehow I never
       | learned about pydoc. It looks like a pretty handy tool!
        
       | winstonsmith wrote:
       | >[In Ruby] There is good support for functional programming with
       | first-class functions, anonymous functions, and closures.
       | 
       | This seems like a blatantly false claim to me since as a Python
       | programmer forced to use Ruby for Sketchup, I have been
       | frustrated by the lack of first-class functions in Ruby.
        
         | tomstuart wrote:
         | I'm interested to learn what "first-class functions" means to
         | you. Ruby has both `Proc` and `Method` which would appear to
         | qualify. Is your frustration that you can't `def foo ... end`
         | and then use bare `foo` to refer to it as a value (vs invoking
         | it)?
        
           | winstonsmith wrote:
           | My frustration is that you can't pass foo as an argument to
           | another function.
        
             | tomstuart wrote:
             | Right, I see, because you have to say `method(:foo)` or `->
             | { foo }` or whatever. To me this is an acceptable syntactic
             | trade-off in exchange for being able to invoke the method
             | with bare `foo` (i.e. variable reads and method calls look
             | the same) but I can see from other comments here that some
             | people dislike that ability anyway. Vive la difference!
        
             | chrisseaton wrote:
             | But you can. Method objects, proc objects, lambda objects,
             | blocks, you've got a wealth of options here in Ruby.
        
       | submeta wrote:
       | Ruby is a beautiful language, but it lost the race against Python
       | long ago. - When I first looked into both some ten years ago, I
       | was undecided what to choose. But even back then googling
       | problems led to much more professionally written blogs / articles
       | about Python. Articles about Ruby were not as profound. That's
       | when I decided to go with Python. And it was the right choice.
       | 
       | ## Edit
       | 
       | What I miss in Python: Ruby always returns a value and does not
       | change structures in place. For instance `data.sort()` in Python
       | will return `None` and change the order in `data`. Ruby won't do
       | that and will return a sorted copy. Like Scheme (a Lisp dialect).
       | In Scheme methods changing data have an exclamation mark as
       | suffix: `(sort! data)` vs `(sort data)`, and it will always
       | return a value. Unlike Python.
        
         | msbarnett wrote:
         | What "lost"? They're both Top 10 most used languages with tens
         | of thousands of open positions currently available for someone
         | competent in either.
         | 
         | Python's the more frequently used of the two industry-wide, but
         | it seems like they both won, just with different crowds.
        
           | dehrmann wrote:
           | I think it's that Ruby has mostly been relegated to Rails,
           | while Python sees use in backend systems, data science,
           | scripts, and as a popular first language.
        
           | disgruntledphd2 wrote:
           | As a professional data scientist, I kinda wish ruby had won
           | for this area, as it's much closer to R conceptually.
           | 
           | Python is fine, the metaobject model is pretty nice, and I've
           | stopped noticing the double underscores ;)
        
         | tomstuart wrote:
         | You may be making a point about what happens by default (and
         | perhaps Ruby's similarity to Scheme?), but in Ruby you can also
         | say `data.sort!` if you want the `data` array modified in-
         | place. It's still returned, though.
        
           | disgruntledphd2 wrote:
           | The hardest thing for me to understand in Python was the
           | baffling tendency of methods to return None.
        
             | teddyh wrote:
             | I think I have read somewhere that they return None in
             | order to explicitly signal that the object has been
             | modified in-place. For example, if you want to have one
             | method which sorts in-place, and another which returns a
             | sorted copy, if then both methods returned a sorted object,
             | it would be too easy to mistakenly call one instead of the
             | other, creating a bug which might not be found for years.
        
         | cortesoft wrote:
         | > Ruby always returns a value and does not change structures in
         | place
         | 
         | The not changing structures in place bit is only for std
         | library things... nothing is stopping code you write from
         | modifying structures in place.
         | 
         | Ruby has the '! means it mutates' convention as well, and the
         | built in methods use it (for example, .sort! on an array
         | modifies the array in place just like your Scheme example).
         | However, again it is just a convention... nothing stops a ruby
         | developer from modifying something in place without a !, or
         | making a method that ends in ! that doesn't modify in place.
         | 
         | The common theme in Ruby is 'nothing stops you from...'
        
       | revskill wrote:
       | Ruby eventually failed in term of quantity of developers, means
       | OOP will eventually died. It's not Ruby's fault, it's just the
       | failure of OOP in general.
       | 
       | My prediction, in about 4 years or more, OOP is just an abandon
       | concept for all programmers.
        
         | gls2ro wrote:
         | Mind you that (let's say) the modern concept of OOP was
         | invented around second part of 60s (with Simula I think) and I
         | think functional a bit earlier maybe in the beginning of 50s
         | (with LISP I think).
         | 
         | Both paradigms have a lot of years of practice and saying that
         | anyone of them will die in 4 years is I think a bit of
         | exaggeration.
         | 
         | Why do you think that in 4 years OOP will be abandoned by
         | programmers? What is the basis for your assertion?
         | 
         | I think it is more probable that we will have a kind of cross-
         | pollination between these two paradigms with maybe newer
         | languages (or evolving existing languages) to borrow concepts
         | and best practices while still providing the core way to design
         | solutions. This is already happening in smaller scale in
         | multiple languages as far as I see it.
        
         | goatlover wrote:
         | Uh huh. And static typing will replace dynamic for all
         | programmers, functional will replace all uses of imperative,
         | nobody will use whitespace indentation, and all emacs users
         | will switch to vim. Also, every programmer will abandon Windows
         | and macOS for Linux.
        
         | tomc1985 wrote:
         | So, C++ and Java have just a couple of years of life left?
        
           | damagednoob wrote:
           | Not too mention C#, Python and for some, Javascript.
        
             | mypalmike wrote:
             | All doomed. Google and Amazon, for example, will rewrite
             | their many millions of lines of Java and C++ in Haskell by
             | 2026.
        
       | amerine wrote:
       | Ruby seems to have cemented itself in my head as one of my
       | favorites. I've built a career from it and am eternally grateful.
        
       | sinsterizme wrote:
       | This is very good timing for me, I just left my python dev job
       | and am starting a job where they use Ruby. I'm very excited to be
       | using Ruby again, it's a much nicer language to use for a variety
       | of reasons I can't possibly enumerate. Ruby's stdlib and
       | surrounding documentation is pristine, I vividly remember being
       | appalled when trying Python for the first time and thinking where
       | the rest of it was. The major issue I find with Ruby (and that I
       | saw mentioned elsewhere in this thread) are imports / requires,
       | which is much too magical in Ruby; Python's import is way saner
        
         | fny wrote:
         | Ruby's imports aren't magical by default. Autoloading
         | frameworks make them so.
        
           | khaledh wrote:
           | The fact that ruby makes this possible means the community
           | will take advantage of it, to the point of abusing it
           | sometimes. This hurts understandability of the code base. Too
           | many times I would open a ruby code base and spend
           | significant amount of time tracing where things are defined
           | (mostly relying on suboptimal searching) because of the lack
           | of explicit imports/requires.
        
             | ysavir wrote:
             | An easy way to do that is to use the Pry gem. If you're in
             | a pry console, you can use `show-method Thing.foo` and it
             | will show you the method, which file and line it's defined
             | in, etc. Pry is a great tool and this feature makes is a
             | blessing.
        
             | Spivak wrote:
             | Python can do this magic too and the community hasn't
             | abused it. Every part of modules and module loading is
             | swappble, mutable to the point where modules can be
             | arbitrary classes if you want.
             | 
             | It would be 2/10 difficulty to add transparent module
             | autoloading to Python because you can just hook into module
             | loading and arbitrarily modify or replace the module
             | objects.
             | 
             | You wouldn't even need a courtesy import because the main
             | module is still a module.
        
           | byroot wrote:
           | Even without an autoloader, Ruby has a single global
           | namespace, so you have access to everything that has been
           | required at any point from anywhere.
           | 
           | If anything autoloaders enforce that constant names match
           | filenames, making it easier to locate the source.
        
         | xavdid wrote:
         | Ha, I just did the same thing. It's definitely a bigger shift
         | than I expected!
         | 
         | I think the biggest difference so far is the quality of dev
         | tooling. Python's native type system has enabled a lot of
         | really good editor functionality. Ruby has Sorbet, which seems
         | good, but it's _much_ slower and more cumbersome. After a save
         | to fix a red squiggly line, there's a 5 second delay before the
         | typechecker / linter figures out the code has updated, run, and
         | updated errors in-editor (note: this could be due to the size
         | of the repo, but it's still a pretty tough experience)
         | 
         | In the company codebase it's pretty well set up and VSCode come
         | pre-configured. But yesterday I tried setting up a little ruby
         | project on my personal machine and couldn't figure out the
         | combination of extensions to make basic auto-complete and jump-
         | to-definition functionality work at all. To their credit,
         | Microsoft has made Python development incredibly
         | straightforward by giving a One Best Way To Do It and making
         | sure there's good LSP support.
         | 
         | Python has its warts for sure, but I've grown to really
         | appreciate the language and its ecosystem.
        
       | lloeki wrote:
       | For some reason it reminded me of _why's unholy:
       | 
       | https://github.com/devyn/unholy/blob/master/README
       | 
       | > You know, it's crazy that Python and Ruby fans find themselves
       | battling so much. While syntax is different, this exercise proves
       | how close they are to each other! And, yes, I like Ruby's syntax
       | and can think much better in it, but it would be nice to share
       | libs with Python folk and not have to wait forever for a mythical
       | VM that runs all possible languages.
        
         | tomc1985 wrote:
         | That's funny.
         | 
         | In a previous job I was the biggest Ruby supporter on a team of
         | Pythonistas. To show them how similar the language was I
         | translated a couple of their scripts from Python to Ruby... it
         | was surprisingly easy and the linecount was about the same
        
           | teddyh wrote:
           | That is all good and well, but which was easier to read and
           | debug?
        
       | helge9210 wrote:
       | On the surface, Ruby and Python are mostly equivalent languages.
       | 
       | Internally, memory management is done differently, for example.
       | 
       | Now add a magic of Ruby on Rails and ActiveSupport to one side
       | and machine learning toolsets to the other.
        
         | viraptor wrote:
         | Not just on the surface. See the ruby to python bytecode
         | compiler: https://github.com/whymirror/unholy
        
       | mountainriver wrote:
       | Really the only reason to use Python is ML, but that is the
       | future of everything so....
        
         | x86x87 wrote:
         | nah. ML is not the future of everything. in fact I believe that
         | as things are going to evolve ML as we see it today is going to
         | be only a tiny fraction of what is going to be used
        
         | goatlover wrote:
         | > Really the only reason to use Python is ML
         | 
         | Not the other scientific and statistical libraries?
         | 
         | > but that is the future of everything so....
         | 
         | So is fusion and flying cars. Maybe one day AGI will be here,
         | but I doubt we humans will be using Python ML libraries at that
         | point.
        
       | jbverschoor wrote:
       | I'm missing the best part - In ruby we have an intuitive and
       | extensive standard library
        
         | aendruk wrote:
         | Of all measures to compare by that seems a particularly ill
         | choice. One of the few things I know about Python is its
         | longstanding reputation for having batteries included.
         | 
         | (But yes, you can pry Enumerable from my cold, dead hands.)
        
       | DonHopkins wrote:
       | "Python is bash for mathematicians." -Michael Slavitch
        
         | BiteCode_dev wrote:
         | Python is used for Web dev (Django), geography (all SIG),
         | system components (part of Unix), pen testing (E.G: scapy), 3d
         | modeling (Blender), sysadmin (ansible), etc.
         | 
         | I've been coded mostly in Python for 15 years and using the
         | scientific stack is a very small parts of what people pay me
         | of, if they ever do.
        
           | DonHopkins wrote:
           | You're misinterpreting that quote as criticism of Python
           | instead of praise. He's not saying that's the ONLY thing that
           | Python is good for.
           | 
           | I've also been programming in Python extensively for at least
           | 20 years, including web application servers like Zope and
           | TurboGears, embedding and extending apps and tools with the
           | Python/C API and SWIG like SimCity, Gnu Radio, Big World
           | MMPORG, robotics, simulations, Blender, Houdini, user
           | interfaces like Tkinter and PyGTK and Sugar, XML processing,
           | OLE integration, BeautifulSoup web page scraping, image
           | processing, character animation, speech synthesis, system
           | administration, infrastructure as code, machine learning,
           | etc.
           | 
           | Python is of my primary programming languages, and I love it.
           | 
           | It's a GOOD thing that mathematicians use Python instead of
           | Bash!
        
             | BiteCode_dev wrote:
             | Mathematicians never used bash. Most of them didn't even
             | touched the command line 10 years ago.
             | 
             | I'm not the one misinterpreting.
        
               | DonHopkins wrote:
               | It's pretty clear and not subject to interpretation that
               | I never claimed mathematicians ever used bash, but just
               | the opposite: they use Python instead.
               | 
               | Bash is an easy way to plug other code together, but it's
               | terrible for math. Python is a much better way to plug
               | other code together, and it's much better at math.
        
       | RomanPushkin wrote:
       | If you're learning Ruby, there is a free copy of my book
       | available (CC BY 4.0 license):
       | 
       | https://leanpub.com/rubyisforfun/ - English
       | 
       | https://leanpub.com/rubyisforfun_ru/ - Po-russki
       | 
       | (if you found typos, you can update the manuscipt
       | https://github.com/ro31337/rubyisforfun)
        
       | boberoni wrote:
       | _> Unlike Python, in Ruby... There are a number of shortcuts
       | that, although give you more to remember, you quickly learn. They
       | tend to make Ruby fun and very productive._
       | 
       | I use Python, but have never tried Ruby. The ecosystem for Python
       | packaging is so chaotic that I've considered switching.
       | 
       | Any Pythonistas/Rubyists here that could point out some Ruby
       | shortcuts that make you more productive?
        
         | batiste wrote:
         | It really doesn't... After years using Ruby my mind never
         | managed to parse its complicated grammar.
        
           | DonHopkins wrote:
           | Guido van Rossum put it this way:
           | 
           | "Again, the templating language seems a weird mixture of HTML
           | and Ruby, and I find Ruby's syntax grating (too many
           | sigils)."
           | 
           | https://www.artima.com/forums/flat.jsp?forum=106&thread=1461.
           | ..
           | 
           | >Then I decided to have a look at Ruby on Rails, just to see
           | what I could learn from the competition. I watched two
           | fascinating movies, but they went a bit too fast to really
           | understand what was going on, and there seemed to be a fair
           | amount of sleight of hand in the examples (a lot of default
           | behavior that just happens to do the right thing for the
           | chosen demo). Again, the templating language seems a weird
           | mixture of HTML and Ruby, and I find Ruby's syntax grating
           | (too many sigils). I believe I heard Greg Stein say recently
           | that if you are really good in Ruby, CSS, HTML and SQL, you
           | can produce great websites quickly with Rails -- but if you
           | don't, you produce lousy websites quickly (just like with
           | PHP).
           | 
           | I quoted Guido's point about Ruby syntax 15 years ago in this
           | lua-l discussion about Lua, Python, Lisp, and Ruby syntax,
           | and the importance of not naming programming languages after
           | naughty bits:
           | 
           | https://lua-l.lua.narkive.com/Ly6vITFE/justify-
           | introducing-l...
           | 
           | >Stephen Kellett 15 years ago
           | 
           | >[...] A little story to explain why in house languages are
           | bad:
           | 
           | >Years ago I worked for a company that had an in-house
           | language (90-94) called Lull. [...]
           | 
           | >(*) Come be real, who uses Lisp for commercial projects?
           | Great language, but too many parens and no one uses it. Its
           | the equivalent of Esperanto. So much promise, so little
           | delivery. [...]
           | 
           | >Don Hopkins 15 years ago
           | 
           | >I read your message about "Lull" and a Dutch guy sitting
           | behind me laughed out loud when I said the name of your
           | language. (My dictionary says "lul" means "prick" or "cock"
           | in slang, so it's a bit more explicit than "dick"!) This just
           | goes to prove that how you name a language is important (but
           | not as important as designing the language so it doesn't
           | suck...)!
           | 
           | >On the "too many parens" excuse for disliking Lisp: so why
           | do you use XML and HTML? They have TWICE the number of
           | parens, which are pointy instead of rounded, but lots of
           | people seem to use them anyway. So "too many parens" is just
           | a convenient and shallow excuse for disliking Lisp that
           | avoids examining the real issue.
           | 
           | >The real problem that many people have with Lisp is because
           | it's perceived as a homosexual programming language, which
           | causes unconscious cognitive dissonance, so people have to
           | grasp for more socially acceptable reasons for disliking the
           | language (like "too many parens"). Nobody wants to just say
           | "I hate Lisp because it sounds gay", so instead they say "too
           | many parens", even though most other languages suffer from
           | too few parens, and are much less readable than Lisp because
           | of their insane hierarchies of precedence rules. Programming
           | tips 101: ALWAYS use parens even if you're sure the
           | precedence rules will make your expression do what you want,
           | because 1) other people need to be able to read the code and
           | 2) you may be wrong. Drop any copy of K&R on the table so it
           | lands on the spine and opens to a commonly used page, and I
           | bet it opens on the table of precedence rules, because that's
           | the page everyone always turns to. Lisp code never suffers
           | from this problem.
           | 
           | >The first thing most typical homophobic Americans think of
           | when they hear the word Lisp is the gay stereotype of
           | speaking with a lisp, so it unconsciously terrifies them. And
           | the fact that "lambda" signifies unity under oppression, and
           | is used as the gay/lesbian/bisexual/transgendered symbol only
           | reinforces that impression:
           | http://en.wikipedia.org/wiki/LGBT_symbol#Lambda ...And then
           | there's the purple cover of Structure and Interpretation of
           | Computer Programs, with the two gay dudes on the cover.
           | 
           | >Anyway, millions of people program in Lisp every day with C
           | syntax, but they just call it JavaScript, and suffer without
           | macros, because of the inferior C syntax.
           | 
           | >-Don
           | 
           | >Fabien 15 years ago
           | 
           | >@Don: your theory is fine for US people, but lack of love
           | for Lisp is also observed in non-English speaking places. I
           | learned quite recently that the word "lisp" also had another
           | meaning than "nail clippings in oatmeal".
           | 
           | >My guess would rather be that Lisp doesn't encourage common
           | idioms and development approaches across people and teams,
           | which makes it hard to:
           | 
           | >- get into code you didn't develop
           | 
           | >- work with more than a couple of teammates
           | 
           | >- find a library that addresses your problem
           | 
           | >- if you have several problems and find a lib to address
           | each of them, get those libs to work together despite their
           | incompatible macro hacks.
           | 
           | >That, and Lisp took waaaay too long to acknowledge its
           | platforms. It pretended to be OS independent, which meant
           | many non-standard, non-compatible ways to interface with
           | OSes, and therefore, plenty of platform issues as soon as you
           | wanted to port or deploy a non-trivial solution. As written
           | somewhere by Paul Graham, "Unix has won, get used to it".
           | 
           | >Don Hopkins 15 years ago
           | 
           | >Now that's some spot-on criticism of Lisp, much better than
           | the "too many parenthesis" excuse that gets thrown around by
           | linguistic homophobes suffering from cognitive dissonance.
           | 
           | >I'm still waiting to hear somebody claim that they refuse to
           | use XML and HTML because they have too many parenthesis
           | (angled brackets). Or for somebody who hates Lisp's
           | parenthesis but tolerates XML and HTML to explain why
           | <foo>bar</foo> is easier to read than (foo bar).
           | 
           | >Perl and C++ have way too much punctuation in general, and
           | Ruby made a cargo cult design mistake in imitating Perl
           | syntax. I agree with Guido van Rossum's comment on Ruby: "I
           | find Ruby's syntax grating (too many sigils)". http://www.art
           | ima.com/forums/flat.jsp?forum=106&thread=14614...
           | 
           | >Wow, in what language does lisp mean nail clippings in
           | oatmeal, and where can I get some of that stuff? It sounds
           | delicious!
           | 
           | >"Using these toolkits is like trying to make a bookshelf out
           | of mashed potatoes." -- Jamie Zawinski, on X-Windows
           | toolkits.
           | 
           | >-Don
           | 
           | [...]
           | 
           | >Fabian: http://en.wikiquote.org/wiki/Larry_Wall look for
           | "Lisp has all the visual appeal of oatmeal with fingernail
           | clippings mixed in")
           | 
           | [...]
        
             | smitty1e wrote:
             | The problem with lisp is `lack` of sigils to give one
             | enough sense of flow.
             | 
             | Moving the ( to the left of the function name somehow feels
             | as disconcerting as gazing upon an non-trivial Haskell
             | function and trying to map the type signature line to the
             | function definition directly following.
             | 
             | Confusion is the mother of "Back to python, where I can
             | knock this out."
        
               | DonHopkins wrote:
               | To my eyes, sigils create turbulence, not flow. And they
               | don't have obvious well defined standard meanings, and
               | aren't self documenting or easy to look up in a manual or
               | dictionary.
               | 
               | Who can even remember how ASCII punctuation should be
               | "alphabetized" in an index, let alone Unicode?
               | 
               | However the pure parens of Lisp code look like concentric
               | ripples on still water, instead of the raging rapids of
               | pathologically punctuated Perl code.
               | 
               | Jack Kerouac and William Shakespeare and Hunter S.
               | Thompson all managed to write beautiful laminar flowing
               | text with words, without resorting to sputtering splashes
               | and eddies of excessive punctuation.
               | 
               | https://www.quora.com/Who-are-some-writers-whose-texts-
               | are-g...
               | 
               | Would you really want to read and maintain somebody
               | else's quirky code written in a programming language
               | designed by e e cummings?
               | 
               | The most difficult and important part of programming is
               | choosing the right words and names, to help the reader
               | understand your meaning and intention.
               | 
               | But there are only a few punctuation characters, unless
               | you resort to inscrutable C++ digraphs, trigraphs,
               | unicode, ambiguous smilies ;), and emojis. (Is that
               | punctuation after the smilie a drool, or an Oxford
               | comma?)
               | 
               | https://en.wikipedia.org/wiki/Digraphs_and_trigraphs
               | 
               | Do you really believe peppering your code with
               | punctuation and emojis instead of using meaningful
               | evocative words makes it "flow" better?
               | 
               | He was making an April Fools joke, but Bjorn Stroustrup's
               | proposal for Generalizing Overloading for C++2000 would
               | have actually improved the language's flow!
               | 
               | https://www.stroustrup.com/whitespace98.pdf
               | 
               | Edit:
               | 
               | My friend and brilliant Lisp hacker Ken Kahn (who teaches
               | kids AI programming with the Snap! visual programming
               | language) was just inspired to explore these stylistic
               | visualizations of Lisp programs with Dall-E:
               | 
               | Ken Kahn:
               | 
               | https://scholar.google.com/citations?user=9hQiyqcAAAAJ&hl
               | =en
               | 
               | Enabling children and beginning programmers to build AI
               | programs:
               | 
               | https://ecraft2learn.github.io/ai/
               | 
               | A detailed painting of a Lisp computer program:
               | 
               | https://drive.google.com/file/d/1pYPNlhD6Q4gvGpjy_SUcuthz
               | 93i...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Ceezanne:
               | 
               | https://drive.google.com/file/d/1SkWQmmpjOg_LhBW0xoEm_9Fs
               | zXa...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Van Gogh:
               | 
               | https://drive.google.com/file/d/16Mno-3mHUPPBmTaeM750SKLf
               | 8hd...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Rembrandt:
               | 
               | https://drive.google.com/file/d/1czti3cQzv6P0SCCjCzyRx-
               | NHMlI...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Herman Brood:
               | 
               | https://drive.google.com/file/d/1EORrmLdH6jY-
               | ShjyzauTvXZ39kW...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Jackson Pollack:
               | 
               | https://drive.google.com/file/d/1Oszo7fqugGTFjpALR1Y9v4AI
               | Xwo...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of El Greco:
               | 
               | https://drive.google.com/file/d/1igFBKYAfGLBFxYPnNPp8UVbz
               | yuA...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Matisse:
               | 
               | https://drive.google.com/file/d/1-Q9jF0gbUXef86BiKEALf6Fe
               | A4e...
               | 
               | A detailed painting of a Lisp computer program in the
               | style of Jan van Eyck:
               | 
               | https://drive.google.com/file/d/1N5l3depTIAwP8dCscZ87_Hm9
               | v5i...
        
               | kazinator wrote:
               | > _Who can even remember how ASCII punctuation should be
               | "alphabetized" in an index, let alone Unicode?_
               | 
               | Ideally, the entries should mostly be one character long,
               | at most two, and appear i a dedicated non-alphanumeric
               | index section that runs for no more than half a page.
        
           | travbrack wrote:
           | Any examples? I always found it easy to grok but I'm not at a
           | very high level so I'm curious where it gets hairy.
        
             | cycomachead wrote:
             | There's a bunch of things to pay attention to in Ruby. I
             | wouldn't say these get too hairy, but they trip students up
             | for very understandable reasons.
             | 
             | * `a ||= b` is not just `a = a || b`, but `a || a = b`
             | 
             | * The distinction between defaults arguments and hash
             | arguments in functional signatures has many edge cases --
             | but it's much much better in Ruby 3.
             | 
             | * There are still 2 pieces of syntax for hashes (`{a: 1}`
             | and `{:a => 1}`) They are the same.
             | 
             | * Curly bases show up a fair bit for a language that's not
             | a braces language. :) They're in hashes, blocks, and %
             | strings. e.g. `%w{a b c}` is the same as `%w|a b c|`.
             | They're also used in string interpolation, e.g. `"Hello,
             | #{name}"`.
             | 
             | * There are sometimes many ways to do the same thing.
             | There's Procs, blocks, and lambdas. % strings work with
             | many characters.
             | 
             | * `unless` for `if not...` and get wonky.
             | 
             | * Overusing "surprise if" e.g. `do_thing if other_thing`
             | can be hard to read.
             | 
             | * It's so easy to monkey-patch and extend primitive
             | classes, you might not realize when libraries do it.
             | 
             | All of these are features that I actually find nice to use
             | in the right contexts. But they can pop up when you don't
             | expect, and they can definitely make Ruby a challenge to
             | learn. That said with a little discipline (or just a linter
             | ;)), I find a lot of Ruby code a joy to read and write.
        
               | IshKebab wrote:
               | > `do_thing if other_thing`
               | 
               | Yeah I don't get why you would deliberately make the flow
               | control confusing and backwards like that. Python list
               | comprehensions are the same. They make the information
               | flow backwards.
               | 
               | This also has the effect of making nesting _really_
               | confusing.
        
               | greenpeas wrote:
               | > > `do_thing if other_thing`
               | 
               | > Yeah I don't get why you would deliberately make the
               | flow control confusing and backwards like that.
               | 
               | I like to use this as function guards, where the first
               | lines in the body of a function can be:
               | return xxx if some_edge_condition?
               | 
               | example: https://github.com/rails/rails/blob/f95c0b7e96eb
               | 36bc3efc0c5b...
        
               | cycomachead wrote:
               | Guard clauses are great, and when used appropriately
               | clean things up. This is pretty much my only use of the
               | pattern.
               | 
               | (Ending boolean-returning methods with a ? is also a
               | great convention in ruby.)
        
               | bobbylarrybobby wrote:
               | if some_edge_condition: return x
        
               | msbarnett wrote:
               | I've written both professionally and personally found
               | Python makes it harder to see the early out, which makes
               | it less valuable/explicit as a guard.
               | 
               | The Ruby pattern is clear up front on what it _is_ rather
               | than being a bag of conditions that you have to get to
               | the end of to discover what they trigger.
        
               | gls2ro wrote:
               | For me this fits more into how I think or how I say
               | things in my mind.
               | 
               | It might be that I am not an english speaker, but for
               | example when I say to someone a list of instructions I
               | usually say it like this:
               | 
               | "Add more water if the dough is dry"
               | 
               | and I don't usually say
               | 
               | "If the dough is dry add more water"
               | 
               | The same for saying for example:
               | 
               | "stop mixing if the dough is starting to tear"
               | 
               | or
               | 
               | "put the bread in the oven when it is ready"
        
               | mypalmike wrote:
               | It's even worse when you combine the two complaints:
               | 
               | do_thing unless other_thing
               | 
               | Which of course you find in many Ruby codebases.
               | 
               | Python list comprehensions seem less painful to me
               | because they read almost like the WHERE clause in SQL
               | simple SELECTs. Definitely not the most straightforward
               | thing one encounters in Python though.
        
               | greenpeas wrote:
               | I don't quite get the distinction in your first item:
               | What's the difference between `a = (a || b)` and `a || (a
               | = b)` ?
        
               | Jabbles wrote:
               | The rabbithole is here:
               | https://stackoverflow.com/q/995593
        
               | greenpeas wrote:
               | wow, thanks. I worked with ruby for more than 5 years,
               | and `||=` never surprised me.
               | 
               | TLDR On the distinction between `a = (a || b)` and `a ||
               | (a = b)`:
               | 
               | * There is no difference when `a` and `b` are local
               | variables (unless `a` is undefined, but that's an edge
               | case)
               | 
               | * The distinction manifests when `a=` is a method. (It
               | could be a `[]=` or some attr_accessor). Then `a = (a ||
               | b)` always invokes `a=`, whereas `a || (a = b)` only
               | invokes `a=` when `a` is falsey.
               | 
               | In essence however, `a ||= b` respects the intuitive
               | definition that it sets `a` to `b` if and only if `a` is
               | falsey.
        
               | cycomachead wrote:
               | Yeah, it's not usually an issue in practice. But I do see
               | students get confused trying things out...and it's likely
               | because learning in an interpreter doesn't often look
               | like "real" code does.
        
           | endorphine wrote:
           | What does this mean, concretely speaking? Do you mean you
           | can't remember the right syntax when trying to program in it?
           | 
           | I know its syntax is complicated but I never felt this has
           | caused me trouble. I guess writing a parser for it would be
           | extremely hard, but that's another story.
        
             | BiteCode_dev wrote:
             | The optional parenthesis kills it for me. It makes scanning
             | the code impossible: you have to understand each line
             | context.
        
               | endorphine wrote:
               | How long do you program in Ruby?
               | 
               | I understand this coming from a newcomer but after a
               | while it felt like second-nature to me. I was curious
               | about parent poster, because they said they are using
               | Ruby for years.
        
               | rubyist5eva wrote:
               | How? I've been writing Ruby and Rails for over a decade
               | and I can't really say it's ever been a problem for me.
        
               | msbarnett wrote:
               | How does this make it confusing? What information do you
               | feel () gives you?
               | 
               | You might say:                     foo().bar().baz()
               | 
               | Ah well these are clearly method calls, they have ().
               | 
               | But this is Ruby:                     foo.bar.baz
               | 
               | These are clearly method calls too, because in Ruby
               | _there's nothing else they could possibly be_. The ()s
               | don't actually disambiguate anything. Unlike C or Java or
               | some other languages with some notion of bare access to
               | internal fields, there are always and only method calls.
        
               | batiste wrote:
               | Yeah, the optional parenthesis is one my biggest
               | complaint with the language.
               | 
               | It just makes things less readable, with not other
               | benefits than making the code look more clever than it
               | is.
        
         | Hamuko wrote:
         | You should probably try some 10-minute Ruby tutorial to see if
         | the syntax doesn't completely scare you off.
        
           | Gordonjcp wrote:
           | When I looked at Ruby (admittedly a long time ago now)
           | everything was 10 minute videos. Is there any actual useful
           | material on it now?
        
             | nomilk wrote:
             | There's ~50 short exercises/lessons here:
             | https://learnrubythehardway.org/book/
             | 
             | I did them when I started out, and occasionally revisit as
             | a refresher. It doesn't teach everything in ruby, but it
             | absolutely gives enough to do just about anything you could
             | want.
        
             | regularfry wrote:
             | The default guide for a long time was the Pickaxe book,
             | which solidly pre-dates the availability of 10-minute
             | videos by several years. There are a fair few links here
             | that you might find useful: https://www.ruby-
             | lang.org/en/documentation/
        
         | AnthonBerg wrote:
         | I like the RubyMine IDE a lot. The code intelligence is very
         | good - it's so good that it tends to teach you Ruby as you use
         | it. Code intelligence as in code navigation, easy access to
         | documentation on the fly, refactoring, code style suggestions.
         | 
         | The same goes for the tooling integration. It works with most
         | of the development tools you'd use with Ruby and captures the
         | integration pretty well in a UI and associated workflow.
         | 
         | Link for your convenience: https://www.jetbrains.com/ruby/
         | 
         | (No affilition except being a paying user.)
        
           | gls2ro wrote:
           | I am using both Vim and RubyMine and I strongly recommend
           | RubyMine for anyone starting with Ruby.
           | 
           | Having the possibility to have a Go to definition for almost
           | any method is great and most of the gems have great code
           | comments with a lot of nice examples.
           | 
           | When I teach people to learn Ruby (I do this sometimes) among
           | the first things I do is I explain to them how to open a gem,
           | look at the source code, read it and then try to use it.
           | 
           | I cannot thank enough the maintainers of the most popular
           | gems for doing such a great job in having great ruby code and
           | good in-file documentation.
        
         | cycomachead wrote:
         | More productive is really hard to say... But I personally
         | prefer Ruby to Python. For smallish scripts, I really like
         | Ruby's backticks for easily executing shell commands. And I
         | find the metaprogramming support in Ruby great for some tasks.
         | I'm not sure if that's what you're getting at.
         | 
         | But especially with "modern" Python features like f-strings and
         | the walrus operator there's not tons of differences that really
         | stand out as "productivity".
         | 
         | One thing to just remember: Ruby is not just the Ruby on Rails
         | community. Rails is a dominate space, but it's not the only
         | thing out there. At the same time, when it comes to scientific
         | computing, ML, etc. the Python ecosystem is incredibly robust.
         | There's plenty of awesome Ruby tools for these things too, but
         | it is not the same.
         | 
         | Ruby and Python are the two languages I primarily teach courses
         | in, and used professionally. Ruby is my cup of tea personally,
         | but they're both modern dynamic interpreted languages.
        
           | ptx wrote:
           | > _For smallish scripts, I really like Ruby 's backticks for
           | easily executing shell commands._
           | 
           | Executing external commands is pretty convenient in Python
           | these days, now that we have subprocess.run [1], and passing
           | the command as a list rather than through the shell seems a
           | lot safer.
           | 
           | Doesn't backticks open up the classic command injection
           | issues (i.e. the same kind problem as SQL injection with non-
           | parameterized queries) unless you're extremely careful to
           | manually apply proper quoting in every single case?
           | 
           | [1] https://docs.python.org/3/library/subprocess.html#subproc
           | ess...
        
             | noirbot wrote:
             | It would, but most of the time when I'm using backticks,
             | it's because I'm writing myself/my team a little helper
             | script that will never get "injected" with anything.
             | Backticks (and the other more featured ways of doing shell
             | commands in ruby) make it really easy to write what amounts
             | to a Bash script, but with a little more features and
             | readability, or pull in some relevant libraries for some
             | more complex task that would be annoying to do in pure
             | Bash.
        
               | ptx wrote:
               | Your use case might be different from mine, but I find
               | that usually there is some parameter needed for the
               | command, usually a filename or sometimes the output from
               | another command. Even if you're not accepting hostile
               | data over the network, you probably want it to work
               | correctly for any valid filename.
               | 
               | With a bash script, or shell commands as strings in
               | general, I can usually with some work be reasonably sure
               | that I'm handling filenames with spaces correctly, so
               | that it doesn't explode when it encounters something
               | unusual... mostly, probably, in most places ... I hope.
               | But what about filenames with newlines? Probably not as
               | correctly. Etc.
               | 
               | With a parameterized API, this all just works and is
               | correct for all cases, so you don't have to think about
               | arcane quoting rules.
        
         | oezi wrote:
         | I think with "shortcuts" they mean things such as $1 (first
         | match group of a regex) or =~ (regex match operator).
         | 
         | I general I rarely feel like I am unproductive in Ruby (or
         | bogged down in boilerplate typing).
        
           | cycomachead wrote:
           | In that case -- I definitely agree Ruby usually gets out of
           | way. It's often my go to for hacking on something, unless
           | it's data science-y.
           | 
           | I'll mention: implicit returns, return if, and safe
           | navigation, the &. operator. Ruby's newer pattern matching
           | features are really cool[1], especially for things like JSON
           | structures, but I've only use started using them. Classes are
           | also super easy to extend.
           | 
           | Many of these things are also incredibly easy to abuse - but
           | they have their places.
           | 
           | [1]: https://docs.ruby-
           | lang.org/en/3.0/syntax/pattern_matching_rd...
        
         | transfire wrote:
         | I'm not sure what "shortcuts" the author is referring, but
         | perhaps...                   x = y || z  # if y is falsy x = z
         | x = f ? y : z  # ternary operator              %w{one two
         | three}  # array of words
         | 
         | And so on.
        
           | endorphine wrote:
           | Also:                   x ||= 1         x &&= 1
           | 
           | and the various built-in methods from Array, Hash,
           | Enumerable, String etc.
        
           | intuxikated wrote:
           | These all exist in python, though you use or/and instead x =
           | y or z x = f and y or z you can also use inline if/else x = y
           | if f else z 3rd one just seems like an array of strings?
           | ["One", "two", "three"] Not needing quotes for single words
           | saves some typing tho.
        
         | pmontra wrote:
         | I loathe most shortcuts: too many things to remember and
         | usually cryptic syntax. Maybe that's because I have to be a
         | polyglot developer (Elixir, JavaScript, Ruby, Python) and I
         | can't remember all the tiny details of each language.
         | 
         | If you want to give a try to Ruby, get to understand blocks
         | quickly. Instead of                 for item in list:
         | work_on(item)
         | 
         | which would work (with a closing end and no : ), the idiomatic
         | way is                 list.each do |item|
         | work_on(item)       end
         | 
         | or the one liner                 list.each {|item|
         | work_on(item)}
         | 
         | Check also map, select, each_with_index, each_with_object, etc.
         | Blocks are fundamental to Ruby for reason that only practice
         | can tell.
        
           | jjgreen wrote:
           | Since "work_on" takes a single argument which is a instance
           | of Item, you'd be better off implementing it as an instance
           | method, so item.work_on. Then you have the even more compact
           | list.each(&:work_on)
        
           | greenpeas wrote:
           | Or with numbered parameters (since ruby 3.0)
           | list.each { work_on(_1) }
        
             | BiteCode_dev wrote:
             | Swift has this as well, and it's really nice.
             | 
             | Doing map(lambda x: x + 1, stuff) or [x + 1 for x in stuff]
             | adds nothing of value for those very simple cases. I wish
             | we had map($1 + 1, stuff), or ever better, stuff |> $1 + 1.
             | 
             | Python does a lot of things right, but for a language with
             | a strong emphasis on the iterator design pattern, I wish it
             | would provide more expressive primitives.
             | 
             | However, it comes with the FP territory, which Python is
             | not well suited for, and it would also imply a higher cost
             | of entry to beginners.
        
             | kofejnik wrote:
             | Quite horrible imo. Creeping closer and closer to Perl with
             | each iteration
        
             | pmontra wrote:
             | Which is exactly the kind of shortcut I loathe.
        
               | greenpeas wrote:
               | you're not alone :) https://bugs.ruby-
               | lang.org/issues/15723
               | 
               | This syntax looks ugly, but it's really nice when writing
               | short scripts. Combined with one line function
               | declarations: `def foo(n)= bar`, it can make an irb
               | session much faster/shorter.
        
         | davidthewatson wrote:
         | I've been using python for two decades and ruby exactly one
         | decade ago for a couple years.
         | 
         | Your comment on packaging is interesting.
         | 
         | My perspective is that packaging on ruby was in nearly the same
         | state ten years ago as python is now.
         | 
         | My team switched ruby package managers several times during the
         | ruby work and none of them ever worked reliably and was a
         | regular root cause of fragility in our builds.
         | 
         | I hope that ruby packaging has settled in that time while
         | python has the same kind of cultural noise that afflicted ruby
         | during that period. Popularity has downsides. Political
         | packaging wars is one of them.
         | 
         | I'm old school enough that I stick with tried and true pip,
         | venv, and .env and its ilk.
         | 
         | There was a long battle in downstream packaging for a while
         | that I just didn't want to be involved in having seen the same
         | thing in ruby.
         | 
         | FWIW, if I were you I'd look at crystal, elixir, or nim. I was
         | very productive in ruby but the near constant battle of
         | wrestling with DSL's that are not concomitant with their parent
         | is, IMHO, to be avoided. I've seen more than one team fall prey
         | to that trap. Caveat emptor - pick your DSL's carefully.
        
           | kawsper wrote:
           | What do you mean by switching packaging managers? Ruby uses
           | Rubygems and Bundler to manage packages.
           | 
           | Are you referring to Ruby version managers that manages
           | different versions of Ruby (rbenv, rvm, asdf, etc.)?
        
             | ByteJockey wrote:
             | They mention doing this a decade ago. They were probably
             | using utilities to manage downloads from the ruby
             | application archive (which would have still been around at
             | the time) and automate running `setup.rb`
        
               | davidthewatson wrote:
               | Yes, all of the above. Sorry for the unclear language.
               | 
               | At the time, I recall it being very distracting when the
               | team was focused on shipping well-tested code. We had a
               | world class devops guy, but we all ran into these build
               | issues frequently enough that it was a regular complaint
               | at retrospectives no matter what tooling we were using at
               | the time or who was using it. It was not long after this
               | that I read Daniel Greenfeld's book on Django that
               | introduced the notion of "vanilla django" and that
               | resonated with me, precisely because our rails tooling
               | was decidedly not vanilla. My take now is that rails can
               | have the same problems with regard to being "off the
               | rails" WRT the aforementioned DSL's and such. I don't
               | think the root cause is ruby as much as there are pockets
               | of rails that are far from what DHH describes.
        
         | nickjj wrote:
         | > Any Pythonistas/Rubyists here that could point out some Ruby
         | shortcuts that make you more productive?
         | 
         | It depends on what you want to do.
         | 
         | If it's building web apps there's Ruby on Rails, which is
         | written in Ruby. In my opinion there's no alternative to this
         | in Python. Sure there's Django but it's not the same even
         | though both are considered batteries included web frameworks.
         | 
         | One nice thing is you'll find both Python and Ruby SDKs for a
         | ton of third party services (like Stripe, etc.). That goes a
         | long ways for building things quickly and with confidence.
         | 
         | Ruby's package manager is also a lot better IMO. It supports
         | proper lock files out of the box and everyone uses gems with
         | bundler. In Python it's a mix of pip, pipenv, poetry, etc. all
         | of which have their own unique issues. With Ruby I never felt
         | like I had to battle this aspect of the language. You just
         | bundle install what you want and creating gems is the same
         | process.
        
           | lloeki wrote:
           | If one wants to get into Ruby, please stay away from Rails as
           | a first step into Ruby-land.
           | 
           | Look into Rack and Sinatra first, _then_ Rails. Even if it 's
           | a short trip it's going to be worth it.
        
             | Lio wrote:
             | This is personal opinion but these days I'd probably swap
             | Sinatra for Roda[1] for small API services.
             | 
             | It's generally faster, uses less memory and is a really
             | good example of well written ruby code, IMHO. I also really
             | like Jeremy Evans' book, Polished Ruby.
             | 
             | 1. http://roda.jeremyevans.net/index.html 2.
             | https://www.packtpub.com/product/polished-ruby-
             | programming/9...
        
           | MatthiasPortzel wrote:
           | > Sure there's Django but it's not the same
           | 
           | Could you elaborate on this? I've used both Django and Rails
           | and in my mind they're direct parallels to each other. For
           | example: in Rails you write migrations and then it generates
           | a schema.rb, and in Django you update your model schema and
           | then it generates migrations.
           | 
           | They have very different philosophies, sure (reading the
           | Rails manifesto made that clear), but from a technical
           | standpoint they have pretty good feature parity.
        
             | likortera wrote:
             | I think you're only considering the backend part of these
             | frameworks.
             | 
             | Rails is really full stack. Django's frontend story is a
             | joke.
        
             | [deleted]
        
         | shaicoleman wrote:
         | There are thousands of little things that make Ruby nice. They
         | all add up to a more enjoyable experience. I'll give you one
         | tiny example:
         | 
         | Python:                   from datetime import date         if
         | date.today().weekday() == 5:           print("It's Saturday")
         | 
         | Ruby:                   require 'date'         puts "It's
         | Saturday" if Date.today.saturday?
        
           | AnonymousPlanet wrote:
           | How do you know which 'Date' your are using. How do you know
           | it's the one from 'date'?
           | 
           | That's like using * imports in Python which is a huge pain
           | once you done even minor refactoring.
        
             | shaicoleman wrote:
             | > How do you know which 'Date' your are using. How do you
             | know it's the one from 'date'?
             | 
             | Ruby allows you to check where a method is defined, e.g.:
             | puts Date.singleton_method(:today).source_location
             | 
             | Although in this case it returns nil because it's
             | implemented in C. But it would return the location if you
             | overrode it.
             | 
             | There are various tools to see what the code is doing:
             | invoking a debugger and stepping into the code, tracing the
             | code execution via TracePoint, etc.
             | 
             | The Zeitwerk autoloader which comes with Rails enforces
             | that the class name matches the filename.
             | 
             | Naming conventions, specs, a quick grep and avoiding
             | generic names make it almost a non-issue in my experience -
             | only happens every few years or so, and usually quite easy
             | to fix.
             | 
             | Ruby gives you a lot of power, but it doesn't stop you from
             | shooting yourself in the foot.
             | 
             | https://m.signalvnoise.com/provide-sharp-knives/
        
             | gedy wrote:
             | Yeah in the Rails shops I've worked with, this "developer
             | productivity" turns into a nightmare with large codebases.
        
           | ouija wrote:
           | I prefer the Python code here. The import is explicit, so if
           | you want to know where "date" comes from, that's easy. In a
           | modern IDE I don't write imports manually anyway.
           | 
           | You could write it as a one-liner in Python as well, but I
           | would prefer not to.                 print("It's Saturday")
           | if date.today().weekday() == 5 else None
           | 
           | That the Python library doesn't define constants for days is
           | unfortunate, but not a limitation of the language.
        
             | by_the_bay wrote:
             | Agreed, in complicated Ruby packages with layers and layers
             | of dependencies it quickly becomes a nightmare to identify
             | which class comes from which import, where it's defined,
             | etc. Never an issue in python
        
             | shaky-carrousel wrote:
             | The ruby oneliner looks way cleaner and more natural than
             | the python one.
        
               | rcfox wrote:
               | Would you ever use either in a real codebase though?
        
               | xipho wrote:
               | As opposed to a fake codebase? This sounds a bit like
               | https://en.wikipedia.org/wiki/No_true_Scotsman.
        
               | mod wrote:
               | No, not as opposed to a fake codebase. I think it's clear
               | what they meant.
               | 
               | One incredibly common alternative to a codebase is a
               | script.
        
               | xipho wrote:
               | Ok, I'll bite. I don't, I think it was a knee-jerk
               | reaction post that didn't think things through for more
               | than a couple seconds. I'm guilty of many of these, it's
               | not the end of the world.
               | 
               | I know many "scripts" that have far more curation,
               | history, and accumulated effort than any "codebase" sensu
               | your post, I don't think this has any relevance to his
               | question. Use is use. "Real" or "Fake" in terms of a
               | standard library like "date" (see my other post) just
               | isn't a useful dichotomy IMO.
        
               | orf wrote:
               | As opposed to either a snippet in a REPL or a comment on
               | hacker news.
        
               | xipho wrote:
               | The code is part of a standard, used-almost-everywhere
               | library, `date`. Code in these libraries, from what I
               | undersand, have a ton of thought behind them. It might
               | follow that there were good real-life use-cases ready to
               | use the code that influenced its presence in that
               | library?
               | 
               | Also: https://github.com/search?l=Ruby&q=Date.today.satur
               | day%3F&ty...
        
               | orf wrote:
               | So the answer to the original question was simply "yes".
        
               | shaky-carrousel wrote:
               | Well, yes. In fact it's the recommended style for simple
               | conditions.
        
             | cutler wrote:
             | The else None is redundant, though. If you want a one-liner
             | in Python just ignore the indentation:                   if
             | date.today().weekday() == 5: print("It's Saturday")
        
             | dragonwriter wrote:
             | Preferring the Python import syntax doesn't preclude
             | preferring the Ruby library design.
        
             | petepete wrote:
             | Why do I need to remember that Saturday is 5?
        
               | d0mine wrote:
               | >>> import calendar         >>> calendar.SATURDAY
               | 5
        
               | petepete wrote:
               | Yeah, I'll take `Date#saturday?` thanks.
        
               | squeaky-clean wrote:
               | ?Por que necesito recordar que el sabado es "Saturday"?
        
               | unixhero wrote:
               | Porque en ese caso no usas un IDE moderno.
        
               | throwawaymaths wrote:
               | Tampoco "if", "for", "while"...
        
               | wiseowise wrote:
               | Rest of the language doesn't bother you?
        
               | quickthrower2 wrote:
               | You are allowed to define your own constants.
        
               | greenpeas wrote:
               | S looks like 5 if you squint. not hard to remember
        
               | jjgreen wrote:
               | So Sunday?
        
               | greenpeas wrote:
               | No! Sunday is 6 because "Sunday" has 6 letters.
        
               | jjgreen wrote:
               | That's it, I'm switching to Python!
        
           | tzs wrote:
           | I think every language I've used has annoyed me in how it
           | handles dates and times.
           | 
           | I've been tempted several times to sit down and repeatedly
           | read Dershowitz and Reingold's book "Calendrical
           | Calculations" [1] cover to cover until I thoroughly
           | understand it, and then write my own date and time library
           | and port it to every language I use.
           | 
           | That would mean that when I learn a new language I'd have to
           | take some time to port my date and time library, but looking
           | at the languages I already know that would have been less
           | than the time it took me to find and learn to deal with the
           | quirks and annoyances in their libraries. I see no reason to
           | believe that this will be different for any future languages
           | I decide to learn.
           | 
           | Yes, I know this would be annoying to whoever has to take
           | over my code when I'm gone, but I tend to stick around on
           | projects until they reach end of life and so there almost
           | never is anyone that comes after me.
           | 
           | [1] https://www.amazon.com/Calendrical-Calculations-Ultimate-
           | Edw...
        
             | scubbo wrote:
             | I cordially invite you to look into the clusterfuck that is
             | Go's treatment of date formatting. Everything else will
             | seem clean and logical by comparison.
             | 
             | Per https://golang.cafe/blog/golang-time-format-
             | example.html:
             | 
             | > Format returns a textual representation of the time value
             | formatted according to layout, which defines the format by
             | showing how the reference time, defined to be Mon Jan 2
             | 15:04:05 -0700 MST 2006 would be displayed if it were the
             | value; it serves as an example of the desired output. The
             | same display rules will then be applied to the time value.
             | 
             | So, for instance, if you want to format a date in ISO
             | format (YYYT-MM-DDTHH:mm:ss), you have to figure out how
             | the reference date would be displayed in that format
             | ("2006-01-02T15:04:05"), and pass that as the format
             | string.
        
               | DangitBobby wrote:
               | I agree, of all the date formatting I've encountered,
               | Go's is the worst.
        
               | dragonwriter wrote:
               | If I didn't know that was actually an accurate
               | description of Go date formatting, I'd think it was
               | satirical.
        
           | politelemon wrote:
           | If I only used Ruby I'd probably prefer the Ruby example. As
           | someone who jumps across many languages, I prefer the first.
           | I found Ruby's approach to things was at many times too
           | clever, to the point of becoming unreadable and cryptic.
           | Python prefers clearness over cleverness.
        
             | heartbreak wrote:
             | How is computing a weekday where the caller (and reader)
             | must know that Monday=0 not cryptic?
        
               | remram wrote:
               | Especially when other systems like cron have used
               | Monday=1 forever
        
               | throwawaymaths wrote:
               | I think the if being an infix operator is a bit
               | "cryptic". I mean IMO it is _easier to read_ - and in
               | reality it 's not a problem, because it's pretty
               | unambiguous what's going on, but some people get annoyed
               | by "oh you can do that in ruby?" Trigger that happens the
               | first few times you see it.
               | 
               | Probably same with fields/methods with a postfix ?
        
               | dragonwriter wrote:
               | > Probably same with fields/methods with a postfix ?
               | 
               | It's not a "postfix ?", it's literally just "?" being
               | part of the identifier name. (It's convention for methods
               | that are boolean predicates.)
               | 
               | Also, Ruby doesn't have fields. (It has instance
               | variables, but they don't have dotted access, so they
               | aren't in the same namespace as methods of the same
               | object the way fields are.)
        
               | mod wrote:
               | I agree that's a little weird, but for me the consequence
               | of it is small.
               | 
               | I'm going to catch that bug quickly.
               | 
               | When Ruby does a magic import, that would sometimes cost
               | me a lot of time tracking it down when I first started
               | with Ruby. I don't remember it being a big deal anymore
               | after a couple of years.
               | 
               | (I like both languages)
        
           | BiteCode_dev wrote:
           | I can't fathom optional parenthesis. In this code it makes it
           | very hard to know if today is an attribute or a method
           | without knowing the context, meaning I can't scan the code, I
           | have to read it carefully.
        
             | jenrzzz wrote:
             | It's always a method. Ruby doesn't expose instance
             | variables unless you define accessor methods for them.
        
               | [deleted]
        
               | fny wrote:
               | I'm going to emphasize this as well. Everything is an
               | object, and everything called on an object is a method.
               | Full stop.
               | 
               | Unlike with other languages, there is no ambiguity here.
               | 
               | In python, you don't know when you dir() an object
               | whether your dealing with a property or method. In Ruby,
               | you are guaranteed it's always a method. A perk is that
               | you don't need parens.
        
               | ek750 wrote:
               | Exactly. Once you get some basics of Ruby, there is no
               | ambiguity, and I find it quite elegant.
               | 
               | And I think I'm in the minority here, but I prefer the
               | cleanliness of optional punctuation.
               | 
               | That feature also allows for fluent DSLs (which seem to
               | be falling out of favor for various reasons), but is one
               | of the reasons I still love Ruby.
               | 
               | To look at the other side, I hate having to constantly
               | add semicolons and parens in other languages. Makes my
               | poor fingers hurt even more than they usually do.
        
             | by_the_bay wrote:
             | Makes reading ruby so much more difficult. Also optional
             | return statements. If you need to refactor a function, it's
             | not always obvious that it's relying on an implicit return
             | and super easy to break things IMO
        
               | gls2ro wrote:
               | (not trying to convince you as I think in this thread no
               | one will be convinced of anything)
               | 
               | Knowing that in Ruby a method will always return its last
               | executed line unless explicitly returned early makes (at
               | least for me) things very easy to get.
               | 
               | A method with two branches will always return the last
               | line of the executed branch, thus you will always know
               | what the response could be.
               | 
               | But this (IMO) is because Ruby OOP where the main concept
               | is that when you are invoking a method you are actually
               | sending a message to that object thus you should get a
               | response. So Ruby makes this way of working with objects
               | universal.
               | 
               | Once you call a method you will get a response.
               | 
               | I find it strange the other way around, working in
               | languages where I need to put return even on the last
               | line of the method. For example after almost one year of
               | full time backend development in Ruby, I needed to write
               | some JS code. I debugged for half an hour why a short
               | function that I wrote was not working properly until I
               | got it: I need to add 'return' to that last line to get
               | the actual result. This was strange for me :)
        
             | nickjj wrote:
             | > I can't fathom optional parenthesis.
             | 
             | I think this kind of falls in line with the idea of Ruby
             | giving you sharp knives[0].
             | 
             | Like you I used to have a love / hate relationship with
             | this because it feels inconsistent to sometimes use
             | parenthesis and sometimes not. In a world where you just
             | want to run Python's Black code formatter and always use
             | parenthesis, having to think about when to use parenthesis
             | feels really tedious.
             | 
             | But I think nowadays I'm happy that they are optional
             | because when you want them to be optional it creates a
             | really nice aesthetic to your code.
             | 
             | For example with Rails you can do: `2.days.ago` and then
             | there's also things that feel like a mini DSL such as
             | `validates :title, :body` or `belongs_to :users`. These
             | just look nicer without parenthesis.
             | 
             | With that said, I do use parenthesis more often than not
             | but it's nice to avoid using them when it makes something
             | look nicer visually.
             | 
             | [0]: https://rubyonrails.org/doctrine#provide-sharp-knives
        
             | sampo wrote:
             | > I can't fathom optional parenthesis.
             | 
             | How about optional dots in Scala?                   if (Day
             | today saturday) println("It's Saturday")
        
               | disgruntledphd2 wrote:
               | Those are worse, but yeah, same principle.
        
             | dragonwriter wrote:
             | > I can't fathom optional parenthesis. In this code it
             | makes it very hard to know if today is an attribute or a
             | method without knowing the context.
             | 
             | Optional parentheses exist because it is impossible for
             | there to be ambiguity: after a dot, if a name starts with a
             | lowercase letter it is a method (and the reference is a
             | call). If it starts with an upper case letter, it is
             | constant (which is not callable as a method.) There are no
             | other possibilities.
             | 
             | "Attributes" in Ruby are literally just getter methods
             | (possibly paired with setter methods.) There is no object-
             | dot-field access to fields (instance variables exist, but
             | outside access to them doesn't use that syntax, but instead
             | goes through a different set of method calls:
             | Object#instance_variable-(get/set)
        
             | z9znz wrote:
             | There may be other things about Ruby that I disagree with,
             | but this is probably my primary disagreement.
             | 
             | It does make code more difficult to understand for exactly
             | the reason you mentioned, and furthermore it can sometimes
             | be disallowed based on the rest of the expression (such
             | that parens are required).
             | 
             | In my own Ruby code, I often use parens when they are
             | optional.
        
             | ByteJockey wrote:
             | Given the context of this thread (comparison of ruby and
             | python), it should be noted that python also has this. You
             | can decorate a method with `@property` and call the method
             | without parentheses.
             | 
             | It's really nice because it means you don't have to pre-
             | wrap all of your properties with accessor methods. They can
             | just be properties, and if something changes, you swap the
             | property out with a decorated method and you don't need to
             | change any code.
        
             | MatthiasPortzel wrote:
             | I started writing ruby a couple weeks ago, and it threw me
             | off at first. But you get used to it very quickly.
        
               | gls2ro wrote:
               | In case you want (and need) to get how to think in Ruby I
               | recommend you to listen to this talk by Sandi Metz (and
               | in general I recommend all her talks even if they are
               | old): https://www.youtube.com/watch?v=XXi_FBrZQiU
               | 
               | It presents OOP in Ruby in such a beautiful way and it
               | takes a while to start thinking like this.
        
         | bsaul wrote:
         | From what i've seen ruby is definitely on the downward slope
         | regarding adoption and python has become a defacto standard in
         | some fields. Its ecosystem is much better in pretty much every
         | domain, so i don't think there's any point switching at the
         | moment, honestly.
        
           | jillesvangurp wrote:
           | I've used both. I slightly prefer python over ruby. But I
           | haven't used either recently.
           | 
           | Ruby's strength is internal DSLs. Python's strength is that
           | it's simple to pick up for people. There's a large community
           | of people that are not primarily programmers that use it. The
           | reason for this is that it is a very easy language to get
           | started with.
           | 
           | Both share the same problem: they are weakly typed scripting
           | languages. Both have in common that type annotations have
           | been retrofitted to the language. But it's an uncomfortable
           | and awkward retrofit in both cases and their respective
           | communities seem to regard using types as an optional and
           | inconvenient thing. Ruby with types of course exists. E.g.
           | Crystal is nice apparently. But I've not really seen that
           | used in the wild.
           | 
           | Python is enormously popular; ruby's popularity seems to have
           | declined a lot. I know a lot of former Ruby programmers that
           | have moved to different languages and only a handful that
           | still use it. It's not an obvious language to pick up for
           | younger programmers. There are so many other languages to
           | choose instead.
           | 
           | IMHO the key innovation in language design in recent years
           | has been type inference. This has lead to a new breed of
           | languages that keep most of what made python and ruby
           | popular: the ability to write code with a minimum of
           | verbosity but without sacrificing type safety. Whether you
           | use Kotlin, Typescript, C#, or even Java: they have type
           | inference now and it reduces the verbosity that comes with
           | having types. Scripting vs. compiled languages is much
           | murkier these days where scripting languages have compilers
           | or transpilers and linters and compiled languages have REPLs
           | and all languages can now run in a browser via WASM anyway.
           | The distinction is just not that relevant anymore.
           | 
           | I write a lot of Kotlin, have dabbled a bit with typescript
           | and I don't think I'll ever use languages without proper
           | types again. Just not worth it for me. I don't see the value
           | of not having a good typing system. Kotlin is interesting to
           | me because internal DSLs are a thing with it; just like they
           | were a thing with Ruby. And it can use javascript as a
           | compilation target. Ruby has a slightly nicer syntax for DSLs
           | than Kotlin for internal DSLs. But I don't mind curly braces
           | and having strong typing enables a lot of good stuff. Like
           | proper IDEs with refactoring, autocompletion, auto-fixes,
           | etc. which are all very nice things to have in a DSL.
           | 
           | I use Kotlin DSLs for writing CSS, HTML components (we use
           | kotlin-js), writing elasticsearch queries (I maintain the
           | multi-platform kt-search library), gradle build files (which
           | uses kotlin script), and quite a few more things. IMHO, it
           | could do a lot of things that python is popular for as well.
        
             | cutler wrote:
             | C# and Java with minimum verbosity? That I'd like to see.
             | Kotlin.js HTML generation is just hideous.
        
             | pmontra wrote:
             | > they are weakly typed
             | 
             | I think you should check the difference between strongly
             | and weakly typed languages [1]
             | 
             | You probably intended dynamically typed.
             | 
             | [1] https://en.wikipedia.org/wiki/Strong_and_weak_typing
        
             | n0tth3dro1ds wrote:
        
               | funnybookbinder wrote:
               | The parentheses become less obtrusive when you indent
               | lisp code properly. Then you just read it according to
               | indentation like Python. I don't find the parentheses
               | problematic.
        
           | keithalewis wrote:
           | Good thinking. You might have to learn something new.
        
         | z9znz wrote:
         | Here's a rough list of benefits of Ruby compared to Python.
         | It's not well organized and the examples are difficult to show
         | in a comment box, but I have pages of notes of why Python is
         | frankly a horrible language compared to Ruby.
         | 
         | Every expression returns a value, so you can assign the result
         | of an if/else or switch statement to a variable. Within your
         | conditional clauses, you don't have to repeat assignments or
         | return values. If the logic goes down that branch, then the
         | last value in that block is the return value.
         | 
         | This also means you don't have to have explicit 'return'
         | statements in functions. Whatever the last value of the last
         | expression is, that's your function return value. You can use
         | an explicit return if you want to exit the function early,
         | however.
         | 
         | Ruby has a switch (case/when) statement. Python finally has
         | this in 3.11 I believe, but it took forever to get.
         | 
         | Hash.dig(). If you have nested hashes (dicts), you can
         | myhash.dig(:top_key, :lower_key, :even_lower_key)
         | 
         | In objects, you can control which attributes can be
         | read/written via attr_reader, attr_writer, attr_accessor. So
         | you can make an attribute have a default getter if you use
         | attr_reader :some_attribute, and then you can write your own
         | setter if you want to control how it gets assigned to. You can
         | even simply not have a setter, so you can effectively make an
         | attribute read-only.
         | 
         | Clean, simple hash initializers: h = Hash.new { |h, k| h[k] = {
         | age: 0, nickname: k } }. So now you can just start assigning to
         | values in h like h["bob"][:attr1] = 28, and now h["bob"] refers
         | to a hash with age 28 and nickname "bob". Yes Python has
         | defaultdict, but it's an extra thing you have to use, and it's
         | clumsy compared to the Ruby approach.
         | 
         | Hash (dict) merging: It's a mess in Python. In ruby it's just
         | h1.merge(h2), or even h1.merge(key_to_update: 123). And you get
         | a new hash as the result. Or you can merge in place with
         | merge!(), changing the original.
         | 
         | Function names with ! and ? greatly simplify function naming
         | (and improve readability). So instead of is_foo(), you just
         | have foo?(). And if you want to indicate that you are doing
         | something destructive, you name it foo!(). This is a common
         | pattern in Ruby libraries, and you often have functions which
         | return a new value and functions with the same name followed by
         | ! which modify the input value. String.strip() returns a new
         | string without leading/trailing whitespace, while strip!()
         | modifies the input string to the same effect.
         | 
         | Python's list comprehensions are arguably ugly and messy and
         | harder to visually parse when reading. Ruby has consistent ways
         | of doing operations on collections. This would take a full page
         | to show examples.
         | 
         | Copying and pasting code in Python often results in new code
         | which is indented wrong (in the wrong scope), and which you
         | must manually fix. This is not a problem in Ruby, since there
         | are actual 'end' statements. Editors know how to properly
         | indent what you paste.
         | 
         | Safe navigation. myobj&.someattr&.foo will give you the value
         | of foo or nil if myobj or someattr don't exist. You have to use
         | ifs to do this in Python.
         | 
         | Array flattening. nested_arrays.flatten(). But in python, you
         | have to use something like list(itertools.chain(*arr)), but
         | that fails if the first element of the list is an int (not an
         | iterable).
         | 
         | Gettings hash/dict keys. In Ruby, you just do myhash.keys and
         | you're done. But in Python there are several ways to get the
         | keys, none of which is as simple and obvious as just keys().
         | 
         | Not allowing typos to silently fail. With Python, you can take
         | an object and assign a value to a non-existent attribute. You
         | might do this accidentally if you have a typo when trying to
         | set an actual attribute: myobj.first_Name = "bob". Python will
         | happily do that, and you'll later debug and wonder why
         | myobj.first_name == "" (and then notice that you have this
         | similarly named attribute now called first_Name). Duh. I guess
         | you could say it's convenient to be able to do this, but it's
         | more a footgun. Ruby will bark at you if you try this.
         | 
         | List sorting in Python is in-place, so you can't non-
         | destructively sort and get the sorted list returned. In Ruby
         | you have a choice. sort() is non destructive, and sort!() is
         | in-place.
         | 
         | I've got more, but this is enough.
        
           | maligree wrote:
           | Using the sorted() built-in returns a new sorted array.
           | Getting keys from a dictionary is literally just calling
           | dict.keys(). Sorry, but I don't think you've used Python
           | enough to offer lists like these.
        
             | z9znz wrote:
             | I stand corrected on the mylist.sort() vs sorted(mylist).
             | But really, such a mistake is more likely with two very
             | different ways of doing the same kind of operation.
             | 
             | In ruby you would just mylist.sort() for a new sorted list
             | (although parens are optional if no arguments, but I show
             | them), or mylist.sort!() to sort mylist in place. You don't
             | have to know two very different things. Plus it's obvious
             | with the !
             | 
             | > Getting keys from a dictionary is literally just calling
             | dict.keys()
             | 
             | Nope. Unless your definition of "keys" is a 'dict_keys'
             | class. Chances are really good that what you wanted was a
             | list of keys, not some object which does not behave exactly
             | like a list. If you want to access the keys by index, you
             | can't do it like mydict.keys()[0] because dict_keys does
             | not have an index method.
             | 
             | Oddly, if you want a list of keys of a dict in Python, you
             | just do list(mydict).
             | 
             | But you can also do [*mydict], which gives you a list of
             | keys but is something special you have to learn.
             | 
             | Here's a fun one. Give me the first key of a dict.
             | 
             | Ruby: mydict.keys.first
             | 
             | Python: (several ways)
             | 
             | next(iter(mydict)) # which makes no sense at all... asking
             | for the next value of something when you're actually asking
             | for the first.
             | 
             | list(mydict)[0]
             | 
             | [*mydict][0]
             | 
             | What if you want the values of the dict? Well, no surprise,
             | Python gives you a dict_values object when you do
             | mydict.values(). Likewise, you can't do listy things with
             | that because it's not a list. You have to convert it to a
             | list with list(mydict.values()). Or you can do the
             | [*mydict.values()] thing.
             | 
             | Python is full of so many inconsistencies, the cognitive
             | overhead is much higher than it needs to be. I would argue
             | that it makes people dumber, because they have to waste
             | mental energy learning weird things for special cases.
             | 
             | But what about the rest of my previous post list?
             | 
             | Here's one I left out. The return-early pattern is common
             | in imperative programming. We like to exit a function as
             | soon as we know things aren't going a certain way.
             | 
             | In Ruby: x = fetch_object("bob") or return "bob not found"
             | 
             | In Python you need 2 or 3 lines (2 if you're using the
             | walrus := operator).
             | 
             | if (x := fetch_object("bob") is None):
             | return "bob not found"
             | 
             | How about setting a value for a variable if it is unset?
             | This is a common thing done when you have variable
             | arguments
             | 
             | Ruby: x ||= "default"
             | 
             | Python: x = x or "default" # not only does it look stupid
             | setting a thing to itself, but it will fail if x is zero.
             | 
             | Edit: fixed asterisks.
        
       ___________________________________________________________________
       (page generated 2022-07-16 23:02 UTC)