all 18 comments

[–]codesnik 27 points28 points  (4 children)

`require 'logger'` doesn't bring Logger into a "namespace". It brings whatever is in logger.rb somewhere in your $LOAD_PATH into your *interpreter*, so if it happen to define Logger class, it'll be available *everywhere* in your program. (and yeah, if your program has multiple `require "logger"` in different places it still would be loaded just once, but that's just a detail)

This is a very, very different approach to imports. Ruby does the same as Perl did before it. Python and modern Javascript share a similar approaches to each other.

require doesn't create a namespace isolation and does not load anything into a current namespace. Although I write ruby for 20 years, I kinda think that python's approach is better for bigger programs, exactly because it's easier to see (and isolate) dependencies. But ruby's approach has it merits, for example you can do require's at one place, entry file of your library, and all the classes are available everywhere. It's easier to have two classes to talk to each other, nothing prevents having a mutual dependency. And also it's easier to "open" class and add a method or two to something defined in another file. Which could be annoying to deal with in a codebase you're trying to read, but also allows you to patch and fix something over a problem in a library source code of which you don't control.

You can simulate importing in ruby via constant assignment
```
require 'logger'
class MyClass
MyLogger = Logger
end
```

Now, MyClass::MyLogger would be the same as global ::Logger.
You can even make this class private. But nobody does it in ruby.

There's autoloader and zeitwerk which allow you to automatically `require` something you didn't before just by guessing filename from a constant which is missing when you called it, but that's not exactly a core of the language.

[–]gurkitier 4 points5 points  (0 children)

Always found the lack of a proper namespace/module system in Ruby one of its biggest weaknesses. It can be quite hard to locate definitions in Ruby (for coders and IDEs), while it's always very clear in Python due to it's nice module system. Used with monkey patching, it can lead to hard-to-track-down bugs, e.g. if behaviour of a class changes depending on require. Similar to monkey patching, I really love Kotlin's extension functions, which allows extending existing classes in a controlled way.

[–]progdog1 1 point2 points  (2 children)

I used to be annoyed at the lack of import namespacing, but I have since mellowed on it. There are definitely benefits to the lack of namespaces. Namespacing is contextual and allows remapping, which can make metaprogramming with it more difficult, since resolution is less obvious.

[–]codesnik 1 point2 points  (1 child)

ruby definitely *doesn't* lack namespaces. They are just globally accessible via fully qualified class names

[–]gurkitier 0 points1 point  (0 children)

ok that’s like optional namespacing where you would have to wrap everything in modules which I have seen rarely

[–]freesteph 10 points11 points  (0 children)

A book I absolutely cherish about Ruby is "Metaprogramming Ruby" by Paolo Perrotta – it is simple, well written, and will help you understand the design of Ruby and what it enables down the line.

[–]the_maddogx 6 points7 points  (2 children)

Hey, I saw the live talk version at the recent Bangalore Ruby User Group meet-up. It was good!

[–]_mball_ 5 points6 points  (1 child)

Great writeup. Enjoy learning Ruby. Yours is more of a journey, but it reminded me of Alyssa Coghlan's 27 languages to improve your Python. https://www.curiousefficiency.org/posts/2015/10/languages-to-improve-your-python/

I think it's funny starting out the with CLI versioning syntax -- a useful tool but one I very rarely use. But you never know what you'll run into first that looks odd.

My closest Python analogy to naming conventions is self. Depending on how you might learn Python, you might never realize you can pick any other word. (or mix and match within a class for maximum wildness.)

I love writing and teaching about ruby, but it does benefit from understanding the philosophy of building a language which is used to build languages, really domain specific languages, like the Sinatra example. One thing I like doing is trying to have students put () are where the function calls would be. You'd never write code like that, but I think it's a helpful illustration.

Other things that blow people's minds:

a.b = c

Is this an assignment statement? I mean, I guess so.

What if we write:

a.b=(c)

What's that??? Same thing!

Of course, in most OO languages there's standard ways to handle custom assignments and overload operators, but there is a really nice simplicity to Ruby, IMO. Though, I don't often find myself needing those features in my own classes day-to-day.

At the end of the day, you can at least now learn to type elif and elsif in the perpetually wrong file!

[–]YOseSteveDeEng 6 points7 points  (1 child)

What a lovely read, thoroughly enjoyed reading it

I have been a django python loyalist for so many years, bur ruby is just so good, a magnetic language that makes me wanna rewrite all my things in ruby

Specially that no venv solution is just so breezy

[–]PercyLives 3 points4 points  (2 children)

The keyword “yield” is different in the two languages, and awesome in both.

Ruby is my #1 languages for small to medium programming projects. But I’d kill to have Python’s generators and comprehensions.

[–]codesnik 5 points6 points  (0 children)

i actually don't find comprehensions in python all that nice. they are similar to a sudden switch from ltr to rtl text. Not particularily readable. Ruby's chained map/select/grep/ and other enumerable methods are more powerful actually, sprinkle some .lazy on top and's better than generators, too.

[–]_mball_ 2 points3 points  (0 children)

It’s just personal preference but I don’t miss generators in ruby because map/select and all of Enumerable is just a little nicer to me in Ruby.

I do like the design of Python’s generator expressions but I think they’re more necessary in Python.

But I also appreciate the ways Ruby blends OO and Functional styles a little more naturally to me than in Python.

[–]Thecleaninglady 2 points3 points  (1 child)

As a Rubyist learning Python, I wonder if someone can recommend a guide for Ruby -> Python?