
Yes, you can stuff anything, even a reference, into the right hand side of a default parameter definition. But in 17 years of using Ruby, I've never done this, never needed to, and never seen anyone else do it. Granted I don't read source of libraries or Rails (except occasionally), so maybe _somewhere_ someone does this. I've read a few Ruby books over the years and never seen this illustrated as a thing to do, even in the Ruby Cookbook book.
(added) To be fair, one thing I have seen which is confusing to people new to programming and applies in Ruby, is if you define a constant EMPTY = [] elsewhere, and you use EMPTY as your default value for a parameter, you will get the same behavior as Python had with just []. That's because EMPTY is a constant reference to an array, but the array is mutable. This would be true for any language which is not immutable. Change the reference? No, that's immutable. Change the contents of the thing it references? Yes.
However, [] would appear to any sane person as an immediate new allocation of an empty array, not an unnamed reference to one spot in memory which gets an empty array allocated for it the first time it is encountered.
In fact, to be very literal, in the Python example the default value is only [] (empty array) once - the first time. In my visit_city() example, after the first run it is now ["some city"]. But if you read that code, and even if you are interactively debugging, the code itself of course does not change. The code still tells you, "Hey, here's a default empty array []". So this utterly fails the principle of least surprise. We expect when we read code that something which appears to be a literal value (or an expression not based on a variable) will evaluate to exactly what it appears to be.
At this point we'll just have to disagree on whether the Python behavior is "sometimes surprising" or "supremely stupid". I would simply put it this way: the use cases for Ruby's (and Swift's and Javascript's and probably any other langauge which offers default function params) fits the more common need, and that Python's opposite behavior is a footgun in a land where people very rarely intentionally want to shoot at feet.
Your final Ruby example is obvious in what it will do, and not shocking at all. And you had to go out of your way to allow that behavior. Nobody does this. No beginner would see this, in a guide or a book. No beginner would accidentally decide to do this.
But beginner and experienced developers alike would come to Python and do def foo(arg=[]):.
There is also a link to GitHub on the app.
Learning resources:
https://careerfoundry.com
https://www.railstutorial.org/book
https://learnrubythehardway.org/book/
Browsing GitHub
Books I've bought:
O'Reilly Ruby Cookbook
The Well-Grounded Rubyist
Beginning Ruby
From Novice to Professional Third Edition
Practical Object-Oriented Design in Ruby: An Agile Primer
If you look through the source code I would enjoy feedback good or bad. I have not been able to find any resources that get past 'hello world' with rack. So what I have wrote was learned from those hello world apps combined with browsing GitHub. I have no idea if I am doing things right or not but it works for now.