Recently, and because of this same we-don't-"do"-Rails sentiment, I was forced into using Java for a web application. So I prototyped a site with Spring and Angular 6, thinking this -- arguably -- represents the "state of the art" when doing a Java web app. Out of frustration, I also cranked up a prototype with Rails. What was taking me literally 160 lines of Java and JS, to build two related models and a form to edit the relationship, took me 3 lines with Rails. Nothing else I've found allows me to be as productive as Rails for writing web applications.
I can understand criticizing Ruby for being clever. There are still magic tricks you can do with it I've never even tried to understand. I can understand criticizing Rails for being obscure. I realize that it took me MANY years to be REALLY effective with it. But if you're telling me the alternative for web applications is ANYTHING related to Java, I'll call you crazy.
I've just inherited a Laravel-based PHP site, which is so old I can't download the version of the framework it uses. Yikes. I did PHP for about 10 years, 20 years ago. It doesn't feel like a lot has changed.
So, I'm honestly asking, as someone who hates Rails: What framework, out there, somewhere, allows me to be as productive as Rails, but which is are "better," somehow?
Rails is not like this. Rails is more like bridge where you have to learn the rules as well as this whole bidding system that fills a book before you can actually play the game.
There is no real magic in Rails, and once you learn the tricks yourself it becomes the most pleasant and productive ecosystem to work with that I've experienced. If you don't bother to learn though, it's going to be awful and slow and opaque.
By the way some of the good ideas in Ruby and Rails have made their way to PHP7 and recent versions of Laravel. So much has changed if your last PHP exposure was 12 years ago, it's not bad now.
For most parts of Rails, I agree. There is one very important one where I don't: ActiveRecord's internal behaviors are opaque enough at most levels where you care about your database to be fairly called "magic". Having to reverse-engineer ActiveRecord to make my database stop puking and to generate a make developers who know Rails but not databases not get upset that now the solution is insufficiently "Rails-y" (whether or not it is correct and whether or not it is faster than the "Rails-y" method that's causing them problems) is not great.
By the time you've gotten there though you've certainly more than figured out how method_missing and different filename based conventions work though, you've seen what Rails is and I'd be curious to find out what you like better!
I still use Ruby nontrivially for stuff like command line tools, though.
Ruby has the easiest data access tools, between ActiveRecord and Sequel (which I prefer), out there. I don't know too many folks who'd disagree with you about that. But where you're happy with Rails taking a few lines, I am as of late big on Kotlin (because I agree with you regarding Java) encouraging me to be correct. I'm building a new product using Spring Boot, Kotlin, and JDBI and while, yes, there's boilerplate - it's not the thing that slows me down. I liken it to touch typing; I don't worry if a programmer can't touch type because getting text onto a screen is never the slowest part of the process.
The thing that slows me down, as it does whenever I'm programming, is thinking, and I've learned over time that Ruby doesn't really help me with that. (A lot of other toolchains, both statically and dynamically typed--hello, TypeScript!--do.) I just don't worry about writing a query with a join - it forces me to understand my domain while I'm writing it, not when it runs and bombs out with an error because I mistyped something or got the relationship wrong in my head because my IntelliSense doesn't exist.
It depends on what you're prioritizing. I went back to the JVM for this project in part for perf, but also because I have a pretty high bar for correctness and I want to make sure my stuff works without writing in/out tests for something as simple as types.
Horses for courses.
(Also, I would submit that the frontend SOTA for "Java" is React, FWIW, same as almost anywhere else.)
I agree with you about the usefulness of a language that helps in thinking about a problem, but I feel like boilerplate is a kind of tech debt we tend to underrate.
Between that and Spring Boot (which is fairly batteries-included but makes it clear when you're going off the happy path in ways I can deal with), I feel remarkably good about my choices with this and similar recent projects.
I'd rather test a well-factored JVM or .NET application than I would any Ruby application I've ever seen in my life, to be frank. I've never, not once, had to write a mock (awful) for a test in a JVM or a .NET application, and the quality of my tests reflect that.
Not true
I'm a former RoR developer (about 5 years) who's now been a full time Elixir developer for two years, so I'll make the obvious suggestion of Phoenix, which is very rails inspired.
It's a little more clunky in the basics, but it has that "magical" feel that hooked me on Rails back in the day, if you want websockets. And there's a new feature coming down the pike, called LiveView[0] that I think could be a total game changer the way Rails was.
For right now, I think of Phoenix as another rails, better in some ways worse in others, but not better enough for most people to switch. But if LiveView pans out the way I think, then it'll absolutely be the killer feature that will get new apps started in Phoenix, and it's only possible due to Elixir/Erlang's concurrency foundation.
Briefly, it takes the React data model – state at the top of the tree, render the tree based on the current state, change the state and the tree re-renders appropriately – and moves it to the server, using websockets to keep the client up to date. So every connected client has its state in a little elixir process, and interacting with the page transparently is calling functions on the server so you can update the DB or whatever with your normal server side code. And if you had a normal server-side rendered view with an `<%= if .... %>` in it, and that condition changed, then voila, that part of the page will change because Phoenix will re-render it, and send down the diff and the page will put in the new HTML.
On all the Rails apps I've worked on we've inevitably added a bit of React here or Angular there to make certain pages a little more dynamic, and then exposed an API for those to hit, and then had frontend and backend development to do. I think what LiveView will provide hits the sweet spot for most apps, so you can stay in your comfortable backend language and get a bit of dynamism for free.
[0] https://dockyard.com/blog/2018/12/12/phoenix-liveview-intera...
It uses websockets, and I think websockets are probably necessary to implement the feature well, but that's not what I'm excited about here.
By the way, Django's inflexible templating language kills productivity (templatetags, as with Java 15 years ago) and the ORM is (how to say it kindly?) lacking in elegance. Django's Model.objects.get(pk=1) vs Rail's Model.find(1) is the least of the problems but I'm short on time now. Because (sarcasm on) we might get confused if we omit objects, what could Model.get possibly mean? (sarcasm off)
Everything in Python seems over engineered as if only very large projects are going to use it, and Django makes no exception. Still, I'll take Python and Django all the times over Java and any of its web frameworks. My personal rankings are:
Ruby/Rails > Elixir/Phoenix > Python/Django >>>> Java/* > JavaScript/* which doesn't have any serious server side framework. I have little direct PHP experience but I'd put it between Python and Java (I managed the developers on medium sized Zend project years ago.)
For me personally, Rails is the best web framework I've seen — but in an age when static typing and other static guarantees are increasingly popular, Ruby as a language is not what people want. It's an artifact of the old Lisp and Smalltalk school of thought.
I use Pipenv currently, but only because it's the best of a bad lot and would jump in a heartbeat if a serious competitor came along. It has its own set of problems (slow, young and idiosyncratic) but offers me at least two things its predecessor didn't: separation of production/dev dependencies and seamless integration with different versions of Python, both of which have been available in Ruby since I started programming in it.
This is a perfect exemplifies my experience with both languages: I have found while Python might be better at a lot of things, the user experience is invariably superior with Ruby efforts and I wish the Python community would put more effort into this area.
What would your state of the art be for starting something new with Rails? / suggestions to become quickly productive
Also, I'm still using RVM. I never made "the switch" to rbenv; I never saw the problem with RVM.
MySQL vs PostgreSQL doesn't matter to me. I've done a lot of both. And Oracle. And SQL Server. I've never seen a problem with using any database with ActiveRecord.
Starting a new project, I just install the latest, stable Ruby, install the bundler gem, then grab the latest, stable Rails, add the basic gems, bundle, and start letting rails generate the basics.
I'm bootstrapping my projects with Vue support, because I think that's the JS framework that fits most-nicely in Rails, and there's always a presentation-heavy page that needs that kind of treatment.
(I'm assuming a Mac or Linux here. I've done this on Windows for a time, but WSL has changed the game there, and I've not actually tried to use it in anger.)
I've found https://github.com/markets/awesome-ruby a really good resource.
One thing I feel stands out is the graphQL gem. It has an unpolished feel...but dang graphql+active record is a killer combo for rapid development!
Sigils in Ruby actually do have strong and clear meanings. And the difference between symbols and strings is a useful distinction. And contrary to your statement, Ruby's stdlib is far more complete and more internally consistent than what you get from Perl or Python, so I'm not sure what your beef is with that.
It's fair not to like particular decisions a language has made, but from what you say, I'm not getting the sense that you understand the decisions Ruby has made well enough to criticize them effectively. Again, it seems like your experience was colored heavily by Rails, and fair enough if that's the case. But stick to criticizing the actual source of your problems.
Is there any reason to use Ruby outside Rails? Its niche seems to completely overlap with Python and modern JavaScript, and those have enormously more ecosystem support and everything that comes along with it: faster VMs, better tooling, large corporations on committees developing language features, etc.
I view Ruby as a sort of “COBOL of Web 2.0”. A generation of programmers learned the trade with it, and it powers important legacy apps, but I can’t imagine building anything new on it.
[Sequel](https://github.com/jeremyevans/sequel) - Sequel is the best ORM I've ever used, in any language. Fast, stable, unbelievably well maintained, and offers great low-level access to the database when you need it.
[Roda](http://roda.jeremyevans.net) - This dynamic routing library is conceptually similar to React Router, in that there is no static list of routes; routing is a function call. But it's faster than React on the server, and has better support for HTTP verb support, database I/O, etc.
As for there being "better tooling" in modern JS, I'm not sure I agree. Babel and ES6 are impressive, and I love writing the code they make possible. But I appreciate being able to write Ruby and know that it will just run. Writing packages for node means choosing one of two incompatible module systems, or adding transpiler bloat.
https://letstalkalgorithms.com/analysis-of-2018-hacker-news-...
As for Ruby outside Rails, have a look at Metasploit, Puppet, Chef, ROM, Rhoda and dry-rb to name just a few.
> Is there any reason to use Ruby outside Rails?
Personally I've disliked Rails for about as long as I've used Ruby (14 years). What appealed to me about Ruby then, and still does boils down to:
- Concise while being by far the most readable language I've worked with. The day something beats Ruby on that, I'll consider switching. If they don't beat it on that, they'll have to bring immense other advantages.
- The flexibility the blocks and meta-programming brings and general Smalltalk influence on the object model.
Ruby is in many ways basically a well supported Stalltalk with pretty syntax.
I'd turn it around: I don't see any reasons not to use Ruby for any of the type of work I do.
> faster VMs, better tooling,
The faster VMs would be nice, but Ruby performance is improving fast enough. In some niches it will matter, but you can call out from Ruby to other languages easily enough - you can run JS, C, Python code from Ruby if you need to, so both the performance and tooling is largely moot for my uses, while I can understand it's an issue for some.
The last time I saw a need to rewrite any code in C to speed it up was a decade ago. Of course that depends what you're doing, but for a lot of areas, it's just "fast enough" that there's little need to worry about speed. Premature optimisation and all that.
> large corporations on committees developing language features, etc.
Yeah, no thanks. That's a good reason for me to prefer Ruby as well.
I enjoyed “Eloquent Ruby” when I needed to learn Ruby for my previous job. Highly recommend it.
Ruby is a perfectly good scripting language. I use it with love and passion to do the kind of stuff other people use Python, Perl or Bash for.
Sure, I could also do the same stuff in perl or python, but personally I find ruby to be far more expressive.
Same reason you'd use any language I suppose. It works as a scripting language, etc. For example, docker-sync, which solves file syncing issues with Docker for Mac (and works on other platforms, but less of an issue there) is written as a Ruby gem.
With AWS recently adding Ruby support to Lambda, my presumption is there's a customer demand there.
Myself, I write a lot of Ruby code that isn't Rails.
I find that it encourages a bad kind of code golf that leads to hard to maintain code.
f(if x then y else z) does not parse.
f((if x then y else z)) does parse.
Funny, I recently made a stack switch from Ruby to Python, and I had the exact opposite impression. Ruby coding style/syntax tends to favor convention over configuration (at least in terms of Rails setup), while Python to me seems less so.
Ruby also seems to me a bit more consistent across it's versions. One of the biggest gripes I've had about Python so far is how many things are broken across various versions of the language, and the odd way some issues have been handled (having two distinctly different types of strings with distinctly different syntax according to encoding for instance). Perhaps Ruby simply doesn't offer familiarity to you individually.
I'm more comfortable with Ruby as I used it much longer, so I may be biased, and I am not shitting on Python either. It has things I don't particularly dig, but that may be my own bias. Both languages have their pros and cons, and both are certainly viable as scripting languages in this particular epoch of programming.
You must be talking about Python 2, the deprecated version for 12 years now, with support ending next year.
Because last time I checked, current, modern Python only has one type of string.
Sure, I am picking out one particular use case, but it isn't uncommon to wrap C code in python scripts to mung data going in and out of it.
You are right though. String manipulation does appear to be easier than Python 2's implementation.
"Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8), all members of this class (such as length or size), as well as its iterators, will still operate in terms of bytes (not actual encoded characters)."
https://stackoverflow.com/questions/1010783/what-encoding-do...
>>> type(b"foo")
<class 'bytes'>
>>> b'foo'[0]
102
It can hold any bytes, it just happens that one way to contruct/represent it can be done with a string-like syntax as a convenience for developers. But you can actually built it in another way, or make it hold data in any other format: >>> bytes([102, 111, 111])
b'foo'
>>> struct.unpack('I', b'\x01\x01\x00\x02')
(33554689, )
Also, std::string is exactly that, a raw byte sequence, with some string operations attached to it. But you don't have any encoding attached to it: https://stackoverflow.com/questions/1010783/what-encoding-do...So it makes sense that Python is treating it has a raw bytes array (what you call "a byte string"): it has no way to know that it is UTF8 or CP850 if you don't tell it.
But because of c/c++ experience or habits from python 2, one tends to confuse the concept of text (represented with the type "str" in python) with some specific low level implementation (the raw bytes array).
Python explicitly avoid this problem, by defining that either you know what it is (utf8 text, big endian number, etc) or you don't (raw bytes array). Manipulating text as a raw byte sequence manually would be the equivalent of manipulating directly the IEEE 754 representation of a number: it's not what you want for a high level scripting language, and hence it's why Python 3 doesn't do that anymore.
Because that's exactly what it is? std::string is a bytes buffer, not actual text. There's no guarantee that the contents of std::string will be in any encoding, let alone a specific one.
I was writing brand-new applications in it for my job as late as early last year
Why the defiant tone?
As I do a lot of Python for a living, and still work on both Python 2 and Python 3, I have talked a lot with people writing new P2 apps in the last few years.
My experience is, either you have very niche constraints, or somebody made an unwise/uneducated engineering decision. Unfortunatly, I meet way more of the second type, and of course, most of them pretend to be of the first.
On what planet was my comment you were replying to FUD? I simply pointed out a few things I'm not fond of in the language (with one point in particular stemming from my own ignorance of the language, which was corrected by folks). I was quite clear in stating that python is a language with pros and cons like any other. At which point did I claim anything to be objectively wrong with the language or spread any FUD whatsoever about using it?
I would, however, like to question this wisdom of always having to run the latest and greatest. Yes there are security considerations but properly hardened, old software and runtimes run fine. You need an actually security guru, though, and not some startup promising turn-key solutions.
And the reason you don't see that for ruby or node is because their community said "move or die". And many, many projects just died. I've seen the graveyard in the corporate world.
There's a tension in programming between being verbosity and ingenuity. More flexible languages and programmers general favor ingenuity, while rigid ones favor verbosity. When people complain about the "magic" in Rails, it's usually because it's a pattern that is new to them, and they would have preferred an older pattern even if it was a more verbose one. Which is fine, but it is a preference amidst a large spectrum of tradeoffs. Unfortunately, many people tend to not see most tradeoffs in software engineering and try to come up with as many reasons as possible for why their way is right and the other way is trivial, stupid, cute, or useless.
A personality difference then. Reading clever code does nothing for me. I'm much happier digging around hulking layered codebases that may look ugly but do something valuable for the user.
I agree that the cuteness of a programming language is just a matter of taste and habit. I'm not going to pretend my criticism was anything deeper than an expression of why I personally dislike having to work in Ruby.
Reading Ruby code always reminds me a bit of trying to understand how xmonad configs work.
E.g. the Sequel example:
require 'sequel'
Nitpick: IMHO import-operators should operate on names not strings, because they essentially are equivalent to "foo := $magic". DB = Sequel.sqlite # memory database, requires sqlite3
Why isn't this a function call? How would I pass options, e.g. the file name here? Why is it Sequel. here, but "sequel" above? Does "require" dump a bunch of unspecified names in my namespace? DB.create_table :items do
primary_key :id
String :name
Float :price
end
What kind of construct is this? Where do all these names ("primary_key", "String", "Float") come from? They were never imported. Is this like ":name => foo" but because that doesn't nest we now have ":name do ... end" for nesting dictionaries? items = DB[:items] # Create a dataset
? # Populate the table
items.insert(:name => 'abc', :price => rand * 100)
items.insert(:name => 'def', :price => rand * 100)
items.insert(:name => 'ghi', :price => rand * 100)
I guess ":name => foo" is some sort of keyword argument. # Print out the number of records
puts "Item count: #{items.count}"
# Print out the average price
puts "The average price is: #{items.avg(:price)}"
If ":name => foo" is some sort of keyword argument, then what value has "price" here?The do...end bits are "blocks" and are the most powerful feature in Ruby, not just because of what they do but also because how they do it. Similarly for other comments.
When I first looked at Rust code it looked weird to me too but once you are familiar with the language a little bit it makes sense. The only thing special about Ruby here is that it allows you to be very terse.
I don't think these need to be at odds with each other. Just because code is useful doesn't mean it needs to be hard to read.
The point being that often the "hulking layered codebase" doesn't need to be.
it still, imo, adds some cognitive overhead, and other orms I've used (grails/gorm, for example), don't try to pluralize. you can pluralize by hand if you want to, but the default is just to name a table whatever the class name is.
What does ActiveRecord consider the plural of "fish"?
How do you define regular? I use both Ruby and JS almost daily, and have previously used Java and python for several years. I find ruby a joy to use and have no issues with 'familiarity'
Every language out there has pros and cons with different set of tradeoffs , you can't point at a language and objectively say X is better than Y.
Ruby has its place and whilst you think Rails is "magic" the internet begs to differ. Of course any framework looks like "magic" if you don't bother digging into implementation details of it. That is the whole point!
The fact that so many successful companies are using rails in production and scaling it, just shows the complete opposite of what you claim: "an extremely resource-intensive web server framework built around assumptions of what web apps were like in 2003."
There has been plenty of times where i wondered how a piece of AR worked and popped over to the Rails github repo and quickly glanced over the details and had no problem understanding it.
You are entitled to your own opinion, but from the outside, it looks like you are just not familiar with ruby.
I think most people including many Rails proponents would agree that Rails has a huge emphasis on "magic" compared to other frameworks. It's a feature. Convention over Configuration implies magic and that is one of Rails' most famous tenets.
Love it or hate it, magic is Rails' modus operandi
Then I found Ruby, and people talked very highly of it. But it had all these "Gems", I couldn't figure out what a Gem was. I didn't know enough. I thought it was like a compiler plugin or something. I thought that just like there were different versions of Java, there were different versions of Ruby called Gems.
Then I found Python, it had "libraries", I knew what a library was, it was something you could download and use in your code. I learned Python and liked it a lot. If Ruby had "libraries" instead of "Gems" I would have learned Ruby instead since I was exposed to it first.
Comments about Ruby say:
- "the webpacker gem"
- "Simple to integrate gems"
- "supported via gems"
- "few dozen obscure gems"
- "the I18n gem"
- "the ruby-each-line gem"
- "vast amount of Ruby gems available"
- "working with so many gems"
Comments about Python say: - "packaged either as a Wheel or an Egg"
- "The numpy module is a wheel"
- "a wheel is specifically not a source distribution"
- "NumPy publishes a lot of wheels for a given release"
All those Python related comments are from one single comment who's author was discussing the technical differences between Eggs and Wheels as packaging formats. Arguably only the last Python comment uses "wheel" as a synonym for "package" or "library".Rust inherited that characteristic, what is not great. It's not a big problem either, but it's there.
I didn't dislike Ruby, but I found Python much more intuitive, as you did, but I suspect that in great part was because it had a similar syntax and concepts as C++/Java.
It was like programming in C with a much cleaner syntax and writing 1/3 of the code, it really was an epiphany.
https://apidock.com/ruby/Hash/flatten
Which doesn't recursively flatten like Array#flatten, even when depth is specified. To me, most of these choices are arbitrary or done for performance reasons which get less compelling with each passing year.
I never know from one day to the next which new concept is going to be thrown at me, or how much I'm going to have to memorize. Whether it's Rails, or Rspec, or any other gem - each has its own ecosystem of technobabble that can't be derived from first principles.
In the end, I don't know what problems Ruby is trying to solve. I find it no faster to write than PHP or Javascript. I find that having multiple ways to specify blocks with begin/end and {} merely increases the permutations I must hold in my head as I'm trying to grok code. This is all very perl-like, which makes sense for a 90's language. But I wouldn't advise learning Ruby or using it in production today. Better to go with a more formal language such as Go/Rust/Swift/Kotlin, even though each of those has its own unique set of flaws and pain points.
P.S. If you are struggling with learning Ruby, I highly recommend learning PHP/Laravel first. It has most of the same concepts as Rails/.NET but builds on the existing context that C-style language programmers tend to be familiar with. Then from there you can create a virtual errata document in your mind to store any arbitrary conventions that Rails introduces.
You have trouble with the use of sigils in Ruby? That seems like an odd complaint. I would have expected you to complain more about MINWAN.
There must be a reason that Ruby dropped few places on Github's Octoverse 2018.
While I was never against Ruby, every time has its tools, it was the culture of the Ruby community which I didn't like. Being a Rubyist was always a good excuse to not help on the frontend or help with some devops.
Now they escape into Elixir which is the next good academic excuse to not help with the frontend because React is so working class...
I get that you are new here, but this place isn't big on shitposting.
Programming languages are different from normal languages because they have different goals, different users and different requirements. The result in of this forced unification in Rails is something that resembles English, if you squint really hard, but in order to do so, it uses a massive amount of non-intuitive assumptions (sorry: conventions) that I as a programmer somehow should know. This makes debugging unnecessary hard. Also, when developing new features I'm constant guessing whether I should this or that form. The only way to find out is trying things out. This is fun as a hobby, but irritating when you're on the clock.
The idea that a programing language can be unified with a normal language is offensive to me both as a programmer and as a writer. They only benefit is that people who are not programmers can dabble around and still make something useful. Which isn't nothing, but not for someone who programs professionally.
Its syntax strongly favors cuteness over familiarity. Wherever Ruby can diverge from expectations to give you a pointless little tickle of whimsical inventiveness instead, it seems to do so.
Visually it looks like an unwanted love child of Pascal and Python. There's no clear rhyme or reason to the use of sigils and keywords.
The standard library and built-in types are acceptable for a mediocre '90s scripting language, I guess. The difference between symbols and strings as hashmap keys is a footgun that opens up endless bugs for the type of glue code that you'd often be writing in Ruby.
Probably the only thing that keeps Ruby afloat is Rails, an extremely resource-intensive web server framework built around assumptions of what web apps were like in 2003. Everything in Rails seems to happen by pooping magic keywords in your code or in file names according to mysterious conventions, so when something goes wrong, you'll have a hell of a time figuring out why Rails isn't calling your code or is generating broken SQL. OTOH it honors the Ruby tradition of doing lots of unexpected and useless cute things like pluralizing words in your database migrations [1].
[1] https://stackoverflow.com/questions/1185035/how-do-i-overrid...