Yes the view layer will be introduced in 2.1. We have hanami-view ready but we need to build hanami-assets and hanami-helpers + add integration code to the main hanami gem.
HN user
solnic
[ my public key: https://keybase.io/solnic; my proof: https://keybase.io/solnic/sigs/JJJ_q-l1IGPrRLbnjvkvrNc8_a-pJMz5ikK5v5XLakU ]
Hanami is not a micro-framework, it is composed of multiple gems though, so if you remove them all you're left with a core of the framework that doesn't do anything except providing an API for plugging in components, configuring them and managing their state.
When it comes to differences - Sinatra is not as feature rich and it's got a less powerful plugin system. Roda has a completely different router using so called Routing Tree, which Hanami doesn't have (it's got something more akin to what Rails has) but it's also highly extendible through plugins, so there is similarity there. A huge difference is that Hanami ships with a very powerful code loading system that supports automatic dependency injection mechanism.
Haha no it's just an example of a custom directory that you can place under app dir We're still thinking about an abstraction for operation-like objects (I actually started experimenting with this a couple of months ago) but I don't think it will become part of the main Hanami stack.
You missed the context of this example - it's just there to show that IF you don't want to use constructor DI, you can put things in lib and they won't become part of the automatic DI system
You're right in principle but not in this case. Zeitwerk is not a regular dependency, it's stable and the risk it will change in an incompatible way is very minimal (reminder - it's used by Rails too). When it comes to dry-rb as deps - dry-rb core team == hanami core team. This means we are on top of the things and we'll ensure that things are evolving together w/o breaking anything.
What you're describing should've been reported as a bug because we do use metaprogramming for DSLs but the "runtime" objects are actually designed to have very minimalistic public API. I can assure you we do not put clean syntax above all else but we do like clean DSLs that reduce boilerplate
Hanami 2.0 doesn’t have any interactors
Your articles are very negative. Basically everything involving Rails is bad and wrong by them. That's what i mean.
I provide critique that some (probably many) Ruby developers don't like and disagree with but my intention isn't to bash something and make it "all bad". I don't recall saying that everything involving Rails is bad and wrong. I had conference talks sharing my appreciation for Rails and various parts of its philosophy that I agree with and try to incorporate in my own projects. There are also things I don't like that are very problematic and I share this with the community as well.
I want Ruby ecosystem, where everybody is free to do their things the way they want, by the rules they want, for whatever motivations they have.
Imagine a ruby gem that becomes super popular because it provides some neat features that plenty of companies can benefit from. Then, for whatever reason, this project introduces some great performance optimizations but they are achieved through monkeypatches. Unfortunately it turns out it breaks Rails in some weird, subtle ways, that are hard to debug. Rails core teams starts getting lots of bug reports about some seemingly unrelated problems, just to realize that it's not a problem in Rails, it's a problem in another library.
Does this make any sense? Nope. That's why people don't monkeypatch in their libraries.
From what I gathered, there's some initiative to move Rails to use Refinements via ActiveSupport, if this happens, then the problem is solved.
And i'm willing to let you have your way and i will respect it but only if you can do the same without being negative about it in every other statement.
It's interesting that you mention respect here - ActiveSupport doesn't respect the rest of the ecosystem. By simply adding new methods to Kernel, Object, NilClass, it reserves them and you really want to avoid having same methods in your library. If you want to tell me "but nothing prevents you from doing this" then you're right, except that I have to think about this because if my lib doesn't work with Rails well, I might as well not build it in the first place because adoption would be non-existant.
FYI I changed the title to "Rails and its Ruby dialect". Thanks for all the comments.
welp :( I'm very sorry about this. I didn't manage to pay for my old domain because I was recovering after an accident (true story, not making any silly excuses). I was aware that it's about to expire but wasn't in a good physical and mental shape and I just forgot to do it. People keep reporting it to me and we're updating URLs every time somebody finds an old link somewhere. I should probably just search through GitHub and send some PRs...
Ah thanks man, I'm very happy to know this. ROM 6.0 is going to be a major improvement Stay tuned!
What makes you think I have negative agendas? My "agenda" is quite positive, I want a Ruby ecosystem where we play by the same rules and Rails is no longer a special snowflake. This way we can evolve faster.
s/Ruby/Rails/g in the article and it makes more sense. You can write pretty good Ruby code, which avoids side-effects, monkey-patches and is easy to test. All you need to do is abandon Rails. There are many modern Ruby projects which make it simpler, see dry-rb.org, rom-rb.org, hanamirb.org and trailblazer.to
Is your time with rails "up" in the sense that you no longer have a substantial day to day use for it
It means that I'm no longer interested in supporting Rails in my gems and I accept the fact it may hurt adoption of these gems. It also means that I will be actively working on an alternative stack that can be used instead of Rails. That's why I support Hanami project and experiment with dry-web project too (which is more like a toolkit for building your own stacks, already supports Roda, and we'll add support for Hanami too).
Apart from that I'll be spending less time on OSS and instead I'll be learning new languages. That's pretty much it.
Hey Sam, great to see you commenting on this :) I started contributing to DM when Dan was already in charge but I was a DM user when you were still working on it.
Anyhow, you made really good points here. I've worked on ORMs for a couple of years before I concluded the same - NOT WORTH THE EFFORT.
My approach with rom-rb is functional, as in this project works more like persistence libs in functional languages, rather than an O/R mapper. I removed the whole idea of mutable objects and managing their state using UoW etc. This simplified the stack a lot, and despite a complete lack of any performance-related tweaks rom-rb is already faster than ActiveRecord.
I also agree with your opinion re validations. I removed this concept from rom-rb as well and built a standalone validation library instead. This works very well.
Cheers!
That's not true, although there's a lot I took from FP. Like avoiding mutable state, and functional composition for data transformations.
This doesn't change the fact my code is OO - I use objects, composition, decoration, delegation and many other OO techniques, and in general try to avoid heavy inheritance-based patterns.
I can understand how people may think I'm trying to use ruby in an awkward way, but this is really not the case.
I dare to disagree. My point about DM being killed by Merb/Rails merge was about what happened back in 2008 with its consequences through all the years. I'm talking about DM1 specifically, if Merb survived and DM could grow with it we would be in a different place now already.
As far as our DM2 efforts go, this really didn't end so bad. rom-rb is growing very fast and we're already in the process of making it easy to use for typical CRUD stuff. Hanami integration will help here a lot too.
`include` is also inheritance, multiple inheritance. I try to avoid inheritance and prefer composition. It is very simple in ruby and very powerful.
yeah it's because I was contributing to many dm-* projects and handling a couple of last releases.
Yes, I was on the core team between 2010-20#{hard-to-tell}. DataMapper was created by Sam Smoot and quickly taken over by Dan Kubb who did a crazy amount of work, practically rewriting it and introducing all the crucial features, and then maintained it for a couple of years with the help from a small group of people.
Thank you my friend, I just fixed it <3
Sorry about that, you can use Reader View in FF which works fine. Crazy part - it's not JS, I tried disabling it and it's still sluggish.
The point I made is that this is all happening in your ORM layer, in ActiveRecord these concerns are not separated. Recent addition of Attributes API at least isolated coercion logic, but it's still part of the ORM, which for me is a mistake.
It's not feasible to have validations centralized. You don't validate objects, you validate data that your system received from somewhere. How it's done depends on the type of this external system, the format and sometimes the context in which you validate, that is specific to your system. This is one of the reasons why AR validations don't scale so well.
Having said that, there are many systems where AR and centralized validation works just fine.
I stopped using statefull objects that make decisions based on their state, in general, validations aside. I don't "delete objects", I make changes in the database instead. When it's a complex operation that requires making decisions based on some information, I simply construct that piece of information from the data in the database and have an object that will know how to use that information to decide what to do. It's a different philosophy that is against some typical OO concepts but I found it to be simpler.
If there's an integration with an external system that can provide data that are valid format-wise but violate some rules defined by my system I still do not need to construct objects that may have broken state. I just build an object that will provide information from that external system which is valid according to rules defined by that system and then ask another object if this piece of information is valid from my system point of view. There's no need to encapsulate everything in one place, in fact, it would be almost always too much responsibility anyway.
I should mention that dry-data will replace virtus in reform, as it's a) faster b) simpler c) more flexible :)
This is exactly what I'm trying to solve with both dry-validation and dry-data.
I wouldn't agree with the low probability of logic errors in AR validations though. I think a DSL with lots of options is a recipe for logic errors. This is the reason why I decided to use predicate logic as the base for dry-validation. It supports nested structures easily, it also supports defining high level rules that rely on results from low-level rules (typically type checking with additional constraints, who would have thought ;)).
I'd love to know more about your idea for using Maybe monad in validations. Using pattern matching crossed my mind more than once but so far I haven't seen a real need for it (in dry-validation).
This is an awesome comment btw. These 4 points describes this problem in a very clear way. It's such a fundamental problem and I believe people should have a good understanding of what it involves.
There's one thing I'd add to this - coercion logic. It's very common that you need to coerce values coming from "the outside", and there are different rules for coercions depending on the context. That's why in dry-data you have different coercible type categories and "form" category is dedicated for web forms.
You'd get these runtime exceptions anyway, but they would be obscure and often hard to debug. Once you define core objects in your system that you construct from external sources (like a database) you establish a contract that the source is trusted and it's expected to provide valid data. If that doesn't happen, for some reason (and it happens), you want to see it as early as possible and a meaningful error can be very helpful.
This obviously doesn't come even close to a statically typed language but I believe it's a huge improvement over the typical approach in Ruby where you...just don't care and hope for the best ;)
dry-validation supports typical validation behavior known from rails where errors are gathered and represented in a string representation. In fact it's much "smarter" than AR validations as it only executes validation functions that are needed and fill in other potential error messages based on rule definitions. This is one of the reasons why it's multiple times faster than AR validations and more extendible.
With dry-data constrained types it's a different story. It raises type errors because we're dealing with lower level objects of your system. Personally I prefer to see a meaningful type error rather than exceptions like "foo called on nil" etc. Not to mention that constrained types increases the chance of spotting type-related bugs earlier.
You are right with everything you wrote except one thing: ship fast and the refactor is not only often extremely difficult and risky, there are cases where it becomes almost impossible.
That's one of the reasons why I've been working on libraries that could provide similar level of convenience and allow you to rapidly prototype something but with a better foundation where things can be refactored more easily.