Rethinking Modularity in Ruby Applications

(noteflakes.com)

15 points | by ciconia 4 days ago ago

1 comments

  • chao- 2 hours ago

    Always cool to see a fresh approach to organizing Ruby projects!

    Like the author, I have experimented with app structures that better suit my project needs than Rails' conventions (having spent more than half my career partially-or-mostly using Ruby, and most of that using Rails). Sometimes that meant building within Rails and bending it to my desires. Sometimes that meant a blank-slate project layout of my own with some glue bits to talk to Rack. Most of the time the juice was not worth the squeeze, but hope springs eternal.

    The one-to-one URL-path-to-folder idea feels neat. I think it would be neat for smaller and/or strictly-API-based projects, but I'm not sure I would prefer it as a strict requirement for large projects. It definitely got my noggin joggin'!

    Eschewing one-psuedo-namespace-constant-per-file as a unit of encapsulation and orchestrating your own import and export also got me thinking, but more skeptically. Working in languages that embrace a free-form import/export, I have found that I prefer the one-encapsulated-unit-per-file style. I am going to dig into the Syntropy implementation and see if it inspires me to feel differently about this.

    Additionally:

    >A further disadvantage is that since everything is global, you might risk touching or referencing classes you shouldn’t, and since dependencies are implicit, those “references by error” may go unnoticed and cause some unexpected (read: undefined) behaviour.

    I suspect the author knows this, but it is not the full story to say that "everything is global". Constants are global in that the Ruby VM's has only one hierarchy that for constant lookup. And because Ruby doesn't have namespaces (yet; we'll see what comes of Box), people reuse the constant hierarchy to approximate a namespace.

    Local variables and instance variables in your "main" object scope are not global, either. Not only are the isolated from other object instances, the variables of the "main" object are not accessible from the class/singleton scope when declaring a class or module!

    And none of these were decisions made by Rails.

    >This approach automates the loading of dependencies, using the directory structure as a representation of the app’s namespace (i.e. classes and modules).

    If only this were true! The file at app/models/user.rb is not required to declare the constant App::Models::User or even Models::User. One of Rails' three original sins is the layout conventions of the app/ folder, and the conventions built on that.

    Yes, technically almost all of it can be configured with some difficulty. My experiments with alternative project layouts using Rails have had mixed success. When you place models and associated core behavior `domain/core/` instead of `app/models`, it's a coin-flip as to whether another developer sees that and says "Oh neat!" or is annoyed. Or when you place pairs of Ruby "view models" and ERB "view templates" in the same directory (e.g. `views/posts/show.rb` alongside `views/posts/show.html.erb`) it throws some people off, even though to me it feels obviously and unquestionably more organized.