How is Ruby different in Japan?
appfolio-engineering.squarespace.com
appfolio-engineering.squarespace.com
Web applications have some very distinct profiles. Most requests:
1. Parse HTTP
2. Parse the request body (likely JSON), build ruby objects from the data.
3. Load data from a datastore, builds ruby objects from the data.
4. Do some manipulation of data.
5. Serialize Ruby objects into a response.
Basically, because of the stateless nature of a web request, most of the work done (ignoring IO) is serializing and deserializing data. By not having Ruby be responsible for the state of our application, we make Ruby responsible for fetching and sending the state.
Now think about a stateful system (like we would have with embedded Ruby). The state is kept within Ruby for the most part. We don't have to hit a data store to restore state every time we want to do something. This significantly changes the operating profile of the application, and therefore the optimization strategy changes.
If it is not accepted, i will do it at the London Elixir meetup.
Even in distributed systems, coordination of data from stateless systems can be a nightmare. Requiring a bit of stickiness simplifies a lot of things.
For example, I've worked on a few large scale adserving auction platforms. One of them had the auction and impression events recorded statelessly (ie each event was generated on a random machine). This required a big hadoop job to match up all the events from a single auction. Another system used sticky events, where all events for an auction would hit the original server that ran the auction. It would store all events for an auction in memory and then flush it to the billing system when the data was finalized. Was it perfect? If the one machine crashed, all pending ad info wad lost. But that didn't happen often so the cost was negligible.
Hence a Lisp hacker decided to write a scripting language which could do so using the Smalltalk object model with a library carefully designed to would work a lot like Perl. The result was Ruby.
Matz doesn't say this anywhere I can find. He usually says he wanted a more object-oriented scripting language and wasn't satisfied with Perl or Python.
Python 2.7 (byte) strings handle Japanese characters just fine for a lot of cases.
I don't think you nor parent have made a clear point for either case
Python 2.7 was released in 2010, 15 years after the release of Ruby. At the time of Ruby's release, you were looking at Python 1.0.
String encoding cause some pretty obtuse errors in non-obvious spots.
irb(main):001:0> str = "\xAA"
=> "\xAA"
irb(main):002:0> str.split('')
ArgumentError: invalid byte sequence in UTF-8
from (irb):2:in `split'
from (irb):2
from /usr/bin/irb:12:in `<main>'
WTF?Second, what do you expect if you have an invalid byte sequence in your UTF-8 string? str.valid_encoding? would have told you that the string contains invalid characters. String#encode gives you fine grained control over how to handle invalid characters in your strings.
Ruby lets you set the encoding by string.
> str = "\xa4"
> puts str
�
> puts str.force_encoding("iso-8859-1").encode("utf-8")
¤
> puts str.force_encoding("iso-8859-16").encode("utf-8")
€ > str = "\xa4"
"" creates a UTF8 string, that one happens to contain an invalid char sequence right off the bat > str.split('')
ArgumentError: invalid byte sequence in UTF-8
... which can only be detected at the worst possible time: when processed at runtime > puts str
�
... and not even always, as sometimes ruby decides to handle strings as just bytes > str.force_encoding("iso-8859-1").encode("utf-8")
... and leaves the responsibility of whether they're bytes or strings, (and which encoding of) solely on the programmer. "force_encoding" is a thing that just should not exist on a string.Python 3 and Go do it the correct way: array of bytes are array of bytes and strings are {array of bytes + encoding}. Ruby could have done it too by introducing a new type or something but chose to do otherwise in the name of a theoretical backwards compatibility that doesn't exist in practice since every singe release of Ruby introduced backwards-incompatible changes anyway.
Ruby's model look much more like array of bytes + encoding to me, how else could I change the encoding for example of a latin-1 string into an invalid utf-8 string with force_encoding? Ruby holds off the validation of the string until it's really needed. Lazy validation doesn't strike me as odd for a dynamic language.
I agree that String#force_encoding would be nice if it were not needed but in the real world you get all kinds of broken encoded data. String#encode most of the time is enough but as a last resort, String#force_encoding is there to use.
I'm a bit surprised that you mention Go because if I look at https://blog.golang.org/strings "Similarly, unless [the literal string] contains UTF-8-breaking escapes like those from the previous section, a regular string literal will also always contain valid UTF-8."
This is exactly the same behavior as in Ruby. I put the invalid byte sequence there deliberately and Ruby and apparently also Go don't have a problem with that.
> in the real world you get all kinds of broken encoded data
> String#encode most of the time is enough but as a last resort, String#force_encoding is there to use.
When your byte arrays and strings get passed around your code soon you don't have a way to validate which one is safe and which is not, which one is a byte array and which is a string.
The thing is not about content, it's about communication and contracts. #force_encoding should not be available on a string, and #encode should not be available on a byte array. If you receive something that may be broken, it should be received into a byte array (b"" in python, []byte in Go), then "cross the gate" to be a string, and that moment is where you eventually perform sanitisation (u"" in python, string in Go). From then on a consumer of your string will be able to assume its content and its declared encoding match.
> I'm a bit surprised that you mention Go [...] This is exactly the same behavior as in Ruby.
Indeed, but you have two types to use and discriminate against, with assorted funcs corresponding to each level of abstraction.
From the Go doc [0]:
> It's important to state right up front that a string holds arbitrary bytes. It is not required to hold Unicode text, UTF-8 text, or any other predefined format. As far as the content of a string is concerned, it is exactly equivalent to a slice of bytes.
I am definitely not concerned about what is in a string. I am concerned about distinguishing between "I just read that bunch of data from somewhere and I'm not yet sure what it is" vs "Ok, that data has been through some earlier process that took guarantees as to what format I expect it to be in". Different abstraction levels. Where Go gets it right is that io.Reader/Writer reads/writes []byte, not string. So you're explicitly acting on your own responsibility when you do:
var b = []byte{0xA4} var s = string(b) foo.IExpectSomeSpecificEncoding(s)
So, when to insert a sanity check becomes obvious, as well as relying on the static type system/method dispatch to check things around for you becomes incredibly useful. and foo.IExpectSomeSpecificEncoding can then use the string as an opaque container.
If you want bytes + encoding in Python 3, you want the 'bytes' type, not the 'str' type.
In Ruby you got strings that are arrays of bytes that are lazily interpreted as string with the set encoding.
In that regard. Ruby strings are more powerful than Python strings as you can handle different encodings. In Python, you have to work around that with the bytes objects to handle non Unicode encodings.
And I think this is borne out by the sheer number of articles that have to be written to remind people who use "strings are bytes in an encoding" languages of just how many assumptions they end up making that turn out to be wrong (most of which boil down to expecting bytes-in-an-encoding types to behave the way Python's string really do behave, as sequences of codepoints rather than as sequences of bytes where there may or may not be one-to-one-correspondence between bytes and codepoints).
True, but that's another debate entirely. The counterpoint is that Python's stance makes it extremely powerful as a consumer of strings has a lot of guarantees about the string he's receiving, which is great for defensive programming.
> "\xAA".force_encoding('binary').split('')
# => ["\xAA"]
If you want a binary string, you can do str = String.new('...', encoding: 'binary')
NOTE: `'binary'` is an alias for `Encoding::ASCII_8BIT`The complaint is not that the default string has no encoding, it's that proper encoding is not validated when creating the string, but only when processing it (and even then it might depend on the actual operation being applied).
So given (1) a string object with (2) a proper encoding, it may still blow up in your face at any point unless you defensively check every string you get with `valid_encoding?`
I thought 1.9 died quite some time ago.
> what do you expect if you have an invalid byte sequence in your UTF-8 string?
What I expected: An error when creating the invalid UTF-8 string literal.
What I got: An when trying to split the UTF-8 string.
It's a very odd place to get an error.
I haven't been paid to write a line of Ruby in over 4 years but I still use it for the occasional hobby project. Not only do I not use Rails for fun, I'd have to be close to starvation before I used it again for profit.
Now I feel the urge to dust off my copy of 'Eloquent Ruby' and write some fun code.
I don't quite have the same hate for Rails, I think. If a client asks for it, I'd consider it. But I also usually tell them I'd rather refer them elsewhere.
The node+react+webpack combo gave web devs the power to process application states and render the UI on the front-end and the back-end using the same code; a feat that is not possible at all with Rails pushing it a little further out of fashion.
Of course, the SPA suffers plenty of criticism, and Rails is still a popular choice with and without an SPA on the front-end, but I think it's fair to say that Rails is no longer the "fun" way to do things (though the most fun doesn't mean the best business or engineering solution).
> Rails was designed at a time before angular brought the SPA into fashion
I dunno that Angular is the relevant point here. Rails (late 2005? I think?) post-dates the public existence of Gmail (public April 2004), a wildly popular SPA. It also post-dates the existence of Google Maps (early 2005). The famous blog post by Jesse James Garrett that coined the acronym "AJAX" is also from early 2005.
The thing that Rails does well was already largely-obsolete before Rails was open-sourced. (Though that is one state-of-the-art buggy whip! Very impressive!)
This means Rails and Angular are doing the same job - the main difference is where data keeping and rendering is done.
You can certainly make distinctions between those data stores, but they have enough in common it's perfectly reasonable to say they're doing many of the same things.
Now, Angular is considerably more horrible than Rails and tries to solve some additional front end problems badly, and its use is a likely indicator that the organization or individual that have decided to employ it aren't capable of making wise technical decisions, so I'd say it's also reasonable to make distinctions between the two on a number of levels. But there's considerable overlap in the kinds of problems they attempt to solve.
Think about these questions: is Rails really "behind" everything involved in a typical web application request/response cycle? Or is there something else behind it? In what situations is Rails not a client? For the situations where it isn't... how common is that setup, and which situations could Angular not cover?
(There's a few, but I suspect they're vanishingly rare.)
You may not have been doing this long enough to remember, but there was a time when "front-end" meant something different than it does now, reasonably so, and there's still some circles where people use it to invoke the layer of an application that generates HTML in back of an HTTP server because of what it's in front of.
> Equating Rails data store backend to Angular's service backend is a poor analogy.
In both cases, you have a given runtime opening up a socket connection through which some protocol exchange negotiates a request-response sequence to a server which provides some representation of application data. What, specifically, is the "poor analogy"?
Sure, everybody understands that the runtime in question is different and execution takes place in different environments. And like I said in my earlier comment, you can make distinctions between types of data stores (though given how common JSON responses are these days, most database developers seem to be working really hard to minimize those distinctions). You can make (some) distinctions between the demands of a multi-request environment and a browser's (likely) single user environment. It doesn't change the fact that there's a reasonable level of consideration at which Angular and Rails are doing the same thing: mapping view actions to controllers, running control code to update/retrieve model state including hitting data sources over the network, and updating the view. An analog doesn't have to be perfectly isomorphic in order to be useful or true.
Now if you really want enlightenment, ask yourself what problems the application of those patterns is meant to solve, and how effective Rails and Angular are at solving them. Also, what parts of the system are "in front" of the browser?
Or don't, I guess, and insist that labels like front-end and back-end represent disparate iron clad categories of platonic computing ideals with an insuperable gulf betwixt.
Does that mean I'm trying to put a stake in the ground on the canonical definitions of front-end vs backend? Hell no, it's totally relative, I'm only commenting within the context of Angular vs Rails so don't read too much into it.
Even today not everybody uses SPAs. Lots of big old school websites generated dynamically on server. Many Django and Rails projects built that way. Also lots of legacy Java stuff and PHP websites (all Wordpress and Drupal sites out there for example, and there are millions).
An Angular app is a JavaScript file that runs in a client's JS environment.
I don't see how there's considerable overlap here?
I'm looking for Rails alternatives.
Something I can't really put my finger on just rubs me in the wrong way in Rails, but using Sinatra felt like shattering chains that were holding me back. Maybe it was partly that I was learning NodeJS at the time, I dunno, but I can't recommend Sinatra enough. This being said I have zero experience with Sinatra in an production environment, so take this anecdote with a shovel(s) of salt.
Now I exclusively use Padrino [0] as the framework to build all my web apps. It is a framework on top of Sinatra that gives you a lot of the Rails goodness, but allows you to be really agnostic in terms of ORMs, Testing/Mock frameworks, rendering platform etc.
[0] - http://padrinorb.com
I have never really understood the craze for Python . I am by no means a guru, but I consider Ruby a far superior language; ( yes, I recognize that the numerous scientific and ML libraries of python make it a logical choice for many projects, but this is sort of like a self fulfilling prophesy)
My love for Ruby declared, I have on occasion wished that we had a "strict" feature in the language similar to ES5 that would permit only the use of Ruby's more straightforward features and also exclude deprecated methods and techniques. This might give the language a deserved boost.
Does anyone know what the most utilized language in Japan is ? And what framework they use there for web projects, if not Rails ?
When looking at new unfamiliar code in Ruby there's just no way of instantly knowing which symbols come from which files/gems. There are conventions, sometimes these are followed well, sometimes not. Either way it adds a lot to the mental load of parsing new code or even old code you've written your self. Ruby's module import system is just too much like C's #include.
As someone who has to now deal with a couple of complicated/convoluted Ruby codebases, that is one of the biggest things I miss from Python too.
The problem is with the module import system, which as you alluded, imports the module structure in a given file into the global namespace. And it imports everything! There's simply no way to say which bits you want and where they should go.
I actually don't really see a reason why the import system could not be changed while keeping the module system in general as is. I wonder if anyone has ever tried something like that...
What I do see is that Python is somewhat less consistent and readable (list comprehensions beyond the simplest ones are unreadable, Ruby's blocks allow cleaner DSLs, len(a) vs a.size, little things like "3.times", allowing "?" and "!" in identifiers). But Python has a bigger and more diverse ecosystem. So although I would prefer Ruby over Python, the ecosystem aspect makes the point moot.
Really wish Ruby had won this war. It's much more pleasant to use.
Github, Basecamp, Twitch, Stripe, Square, AirBnB, Shopifly, Cookpad, and many more. All these are very successful site that are using Ruby ( Not necessarily Rails ) and most of them profitable.
If each or them could fund a 20-33% Salary of an additional Core Dev you instantly have 3 - 4 people working on it Full time.
So I have been thinking on this for sometime, It is because the Ruby community and the world as a whole does not want to donate? Or are we lacking someone to push this and ask for some help when needed?
I came to say the same thing.
Its such an obviously good idea. It seems all that is needed is a champion for this cause.
Of those I know both Dropbox and Google have employed Gudio Von Rossum, and various other Python core devs are also employed full time.
Overall it seems that Python is much more community driven than Ruby. Python is interesting in that it has several big camps, including web dev, systems programming/automation, scientific usage, machine learning, etc, and all of these communities are fairly self sufficient but also contribute back to the main language.
'%s won $%i' % ['herbst', 5000] 5.times do
print "s"
end (0 ... 5).each do |x|
print (x + 1)
end
Idiomatic Python: for x in range(0, 5):
print (x + 1)
To understand Ruby, you need to know what || does, and the overall sequencing of the words as you read that construct is somewhat unnatural for English. Python is comparatively easier to parse with no prior background.It is definitely possible to write Ruby in a way that's still highly readable. But from what I've seen of real world Ruby code, that's not the way it tends to be written - idiomatic Ruby values expressiveness and DRY, so you see blocks and various terse syntactic sugar used all over the place; lots of "clever" code in general. There's nothing wrong with that - I generally prefer expressiveness over readability myself - but many people do not.
Basically what I'm saying is that the differences are very minor compared to differences vs, for example, other languages (Java, Scala, C++, etc). So from that perspective there's not much to complain about. I just have a slight bias towards Ruby, I find it a little more readable (in a small way).
To me it is more expressive of my intent to say "0 to 5, for each, do something" than "for something in the 0 to 5 range do something"
Also you happened upon what peeves me most about Python, you are not actually looping from 0 to 5 since range is inclusive at the start, but exclusive at the end. So while (0..5) gives you 0, 1, 2, 3, 4, and 5, range(0,5) will get you just 0, 1, 2, 3, and 4. Of course it's easier if you think that range() is rather "I want to take X steps", so if you just want to step 5 times range(5) does exactly what you need it to do.
'example string'[3:8] # gives you 5 characters.
2.3.3 :001 > 'example string'[3, 5]
=> "mple "
Instead of having to think before hand what indexes thous would be.But there are also many cases where length is more desirable.
Ditto with ranges - both end-inclusive and end-exclusive ranges are useful in different cases. I kinda like the fact that Ruby lets you choose, but I think that .. vs ... syntax distinction is too subtle and likely to cause bugs.
I kinda like the way Nim does it: .. for inclusive, and ..< for exclusive - e.g. 1..<10. They also use special syntax for count-from-end, instead of negative indices, which is also a good thing IMO (the decision to index from start or from end is usually something that's not going to change at runtime; but with negative indexing, it might inadvertently do so if you underflow when computing the index).
1.upto(5) do |x|
puts x
end
is pretty idiomatic. So I don't see your point. print("s\n" * 5)
Which is more concise and valid in both.Have you looked at the C source of Ruby? :) In terms of that, Python is far, far superior to ruby.
EDIT: to clarify, CPython is much cleaner than MRI, and has a much-better-documented API for extensions. This is what I believe part of the reason that Python has a much better coverage for scientific packages.
Ruby is unfortunately also the slowest. But not because of the VM implementation, only because of the everything is a method architecture, even for the simplest primitives. The ruby API is pure and clean, this is what makes it slow.
For the python or perl API too much inner state needs to be handled, which makes it slow also. Because you cannot use a better design for data and code. Only php made significant advantages there recently, so you don't have to worry about inefficient data and code, only about the eye blead VM.
Python's C API could be argued that it uses too much abstraction, but it definitely makes it that much easier to write extensions.
The languages are pretty similar. The community attitudes are different.
If you ever find yourself pulling back the curtain of many ruby modules, it's time to dig in and swear as you go.
Both languages have metaclasses but Ruby's are simpler to grasp and more fluid in how they're applied because they're more run time oriented rather than instantiation time oriented like Python's. In fact Python in general tries to make more of a distinction between the instantiation and runtime environments making it a bit more restricted. All this means the average Ruby coder tends to use metaclasses almost everywhere and certainly a lot more than the average Python coder.
Ironically even string processing with encodings is harder in Python 3 than Ruby 1.9 (these are the versions in which both languages modernised their Unicode support). Python's insistence on Unicode everywhere is problematic in places like Japan where there are still extant competing encoding standards that are not fully recoverable when doing a round trip via Unicode. Even ignoring Japan though, Python has had to put in all sorts of hacks to deal with corner cases like the fact that command line parameters or file system names don't always have to use Unicode encodings. 95% of the time you can be ignorant of all this in Python and stuff will just work... but it's a massive pain when you're dealing with the other 5%. I genuinely still don't know if the Python 3 or Ruby 1.9 approach is better... Python's is purer and initially I liked it better conceptually... but having had to apply it practically I'm no longer so convinced.
Finally, I assume you weren't comparing blocks and decorators as somehow equivalent features. It might be worth adding that it's pretty easy to add syntactically pleasing decorators to Ruby without needing special built in syntax, by leveraging Ruby's metaprogramming capabilities. It just tends not to be used as often in Ruby because there's usually different ways to express the equivalent concept.
But while on the topic, blocks are probably the killer feature that makes Ruby more powerful. They essentially allow you to easily change the context of an individual method call in very arbitrary ways. Yes you can do it by passing in named functions or even function pointers in C, but none of this is as syntactically coherent as blocks in Ruby.
If you want a practical example of how this makes Ruby powerful take a look at Rake. It's basically a Make equivalent written in Ruby. The nice thing is that you never leave Ruby, all you do is add a "require 'rake'" at the top of your Ruby file and you now have enough DSL machinery to be able to write pretty nice rule syntax without ever having to write a parser for a custom language (and leaving the power of Ruby behind).
I don't expect any of this to be particularly convincing. The difference in power only becomes obvious when you start writing idiomatically in both languages. When I first started writing Python I tended to write it more like idiomatic Ruby and it was not pretty. Overall Python and Ruby are at a fairly similar level to each other but Ruby definitely has a bit of an edge in terms of expressiveness.
Being a Python fan myself and a hater of "DSL all the things", I still like to have a good POV from the other side.
Why is this not a thing ?
See my previous comment
About more non Rails stuff, I started writing small text processing scripts in Ruby a few years ago. I wrote them in Perl before, but I eventually got more at ease with Ruby, notwithstanding the compact convenience of Perl's while (<>) loop and the implicit input variable. I also made a mruby program run on AWS Lambda just because I could. Interesting but probably not extremely useful in that context (pun intended).
I wonder if there will be a second Ruby wave from Japan, if their community keeps growing and their use cases start reaching abroad. Remember that the first wave (Rails) was actually from the USA.
The "-n" switch adds an implicit "while gets; ....; end" loop, leaving the input line in $_. "-a" will do "$F = $_.split", which means it splits on the contents of "$;" which can be set with "-F" like with awk.
E.g.:
ruby -naF[someseparator] -e '[some ruby expression]'
Is equivalent to wrapping [some ruby expression] in: $; = [someseparator]
while gets
$F = $_.split($;)
end
Which incidentally also gives a halfway decent awk impersonation given that Ruby also supports awk-like BEGIN {} and END{}.Overall I found the philosophy to Ruby to be a bit more elegant than Python's, but I struggled with some of Ruby's philosophies about what an object is and how to store them.
In general I enjoy Ruby as a general purpose language, but code I wrote to interact with REST APIs was eventually replaced with Python at my work because "not enough people know Ruby".
What is Ruby's killer feature to help drive adoption in situations such as these? By "these" I mean as a general-purpose scripting language.
I find Ruby to be much easier to read and understand than Python but I have 10 years of customers paying me to write Ruby vs one in Python. I assure you that it would be the other way around if I had worked in Python for 10 years.
I never picked Python for my own projects in all those years because I find many of its design choices weird and painful (I joke saying it's Ruby for the masochist), but that is very subjective. People liking Python consider good even what I find to be objective weaknesses of Python (example: only one line lambdas.) This means that probably both languages are good enough.
This is nothing particularly insightful on its own, of course, but this philosophy in terms of "what language do I write my code in" is worth a retread every now and then.
If you're good at designing backends and the project is yours, no problem. You'll have to work more and reinvent some wheels but you'll get exactly what you want, no compromises.
If the project is for a customer and then you move on to another customer, do your best to leave a project that the next developer can understand easily. As every Django project can look very different, that's not granted.
On the other side every Rails project looks the same and every project I moved into was well organized. I'm a freelance and my customers call me to add features or fix things. They don't have time and budget for heavy refactoring so those multi thousand lines files are still there, minus some code I managed to extract.
[1] The poor defaults are that a single views.py and controller/default.py are almost all you need to run the app. Hence the 2670 lines default.py I'm wrestling against now. Luckily that was a small intranet backend.
https://pragtob.wordpress.com/2017/01/24/benchmarking-a-go-a...
Then it seemed like one day some years later, a very faddish, I will be blunt, charlatan type seemed to dominate that discussion. This is the type that confuses ruby with rails, git with github, the internet with the web. They are using ruby in the same way that the old ASP crowd would have used Visual Basic.
I was never involved in any of this, just watching from the sidelines, but it does seem like a bit of a shame.
That said, Rails is hardly the only framework that has brought Ruby to the communities outside of Japan. Chef/Puppet/Fluentd played a key role in bringing Ruby to the ops world while books like "Understanding Computing" by Tom Stuart demonstrates Ruby's potential beyond web programming.
There's a tangible tension between Rails fanatics and sans-Rails Rubyists, but they have needed each other to get where they are today.
I used Ruby because my groupmates found Lisp, ML or Haskell too difficult, and Ruby has(had) a very nice Set datatype plus pretty good metaprogramming and DSL abilities.
The code was on Github for some time and it was always funny to see recruiters reaching me, looking for people with > X years Rails experience, as they always equated Ruby to Rails.
American audiences often ask, "why would you want an embedded Ruby?"
You might as well ask "why would you want an embedded Python?"... the answer to that is fairly obvious to anyone who knows Python and C, and who has done embedded programming. So why is it less obvious to those same programmers why someone would want an embedded ruby?
[1] http://maisonbisson.com/post/17379/transcend-wifi-sd-card-ha...
In case you misunderstood: The above is not about running Linux off of a stored diskimage on an SD card. The ARM SoC in question fits in an SDcard. They're intended for e.g. putting in your camera so you can have wireless, wifi access to the images on the SDcard.
Other than that I agree - there's certainly still room for both. But the point is you can physically fit a Linux capable computer in an SDcard form factor, and drawing 100mA, which means the niches where smaller micro-controllers is the only alternative have narrowed accordingly.
No way. Perl used to be quite popular.
Ruby 1995
But I don't know if Python was good with Japanese text in 4 years after inception.
However, Japanese often don't want Unicode, because of Han unification, and the associated controversy. Thus, other encodings are often preferred, and languages that can handle them in a transparent way have the advantage. It's largely for this reason that Ruby avoided a Unicode string type for a long time, treating strings mostly as raw byte arrays, with a few places that needed encoding supporting them on an ad-hoc basis.
In Ruby 1.9 (2007), they finally added encoding-aware strings; but unlike Python 3, where the encoding is always Unicode, in Ruby the encoding can be anything, and string is bytes + encoding. So you can do UTF-8, but you can also do e.g. Shift_JIS (which many Japanese users prefer). The cost is that it means that e.g. a+b is no longer always valid for two arbitrary strings, if they are in different encodings that cannot be reconciled.
"Unicode" strings were added to Python 2.0 (October 2000), they're the default since Python 3 (December 2008).
To this day, Ruby does not have "unicode" strings, it has byte strings, which since 1.9 (December 2007) can have an associated encoding.
Ruby has never had text strings at all. It added an encoding property to bytestrings in 2007.
Just use Rails, it scales just fine. Your hand-coded DB layer for your microservice will never be as good as ActiveRecord if you aren't Facebook.
If I had to pick the top things that Rails excels at, I'd point to ActiveModel and resourceful routing. I know REST isn't the hotness any more, but it sure is great for CRUD web sites or APIs, and Rails makes setting up database models, associations, and REST routes a breeze.
One strong point is that it's full Ruby, so there is no need to learn another language. This means that one could write the application in the views (just like vanilla PHP) but in my experience nobody does it.
Another nice feature is that every instance variable of the controller is available in the view. No need to waste time to declare them and get an extra chance to add some bug (I'm looking at you, Django.) I still remember how good it felt coming from Java Struts in 2005.
If you send the wrong HTML tag, the content just might look a little funny to the end user. If you send the wrong datatype to an API client, it generally won't be able to do anything with it, and may not fail gracefully at that. Constructs to ensure you cannot make that mistake are invaluable in API design.
I wasn't looking for advice about web frameworks, but since you offered it, do you believe developers using other web frameworks are misguided in doing so? It's not like Rails is the only game in town, comparable solutions exist.
https://insights.stackoverflow.com/trends?tags=ruby-on-rails...
And for Ruby also:
https://insights.stackoverflow.com/trends?tags=ruby%2Cpython
As a Ruby developer who has used Ruby since 2005 without using Rails, that's news to me.
It declining here. Whatever value you place on that.
Edit:
Oddly that page describes May 2016 as it's high (#8), but that's not reflected on the charts.
The company is under new ownership/management since very recently ... perhaps Amir or someone will look at regional situations and gain more mindshare for the platform.
IMO on the mobile side, there was already a strong native culture that made it a harder sell to go the cross platform route.