I'd have to say this is very exciting, and something that from which the Ruby web community could benefit greatly. Having the boiler plate cases covered for data binding and synchronization across the client and server could really increase productivity for modern web application. For anything else that doesn't fit that mold, a developer could always degrade to using their front end framework of choice with Websockets or AJAX back by REST APIs where appropriate.
Opal is a really neat gem for translating Ruby to JavaScript. For those who know some math, I used it to convert some Ruby code I had written to perform finite field arithmetic (https://github.com/robertzk/FiniteFields) into an interactive webpage (http://therobert.org/finite_fields/). It would be just as trivial to do with Volt.
Because Javascript is a horrible language to code in and debug.
If you're a Ruby programmer, you don't need to learn a new language, and you can have confidence that the Opal guys have looked after a lot of the issues you're not experienced enough to understand.
Your question is like asking a C programmer "why not just use assembler?" or an assembly programmer "why not just toggle 1s and 0s in, because ultimately your code is going to get turned into binary eventually, right?"
Abstractions and different models of describing a problem solutions are helpful for a multitude of reasons.
While JavaScript is a terrible language to debug, machine-generated JavaScript is little better, and leaves you guessing which code you need to change and how in order to affect it.
> In this particular case, Ruby is not being compiled to JavaScript but being transpired.
First, "transpiled" not "transpired".
Second, "transpiled" is a special case of "compiled", so you can never correctly say that something is not being compiled but is being transpiled, in the same way you can't say something is not a rectangle but is a square.
it's a mix, some stuff is high level (closure), some is low level (for loop before ECMA6). This is very uncomfortable when you're learning it, you never know on which side you are.
Instead of syncing data between the client and server via HTTP, volt uses a persistent connection between the client and server. When data updated on one client, it is updated in the database and any other listening clients. (With almost no setup code needed)
---
In .NET land, I used SignalR when it first came out and it has since been baked into ASP.Net.
In Rails, I use Pusher, a paid for service because it's just easy to use and iterate.
If this works like it says on the tin I am excited! Beyond excited! My one question though is how many users can it support? How many people can be 'listening' for a broadcast.
What's the problem that this framework is trying to solve? I can't imagine that Ruby code will correctly compile into every possible use case for JavaScript. Even if it does I won't be able to leverage any gems, which is the real power of a mature server side language. It seems like this is just a crutch for Ruby web developers to use a familiar syntax and avoid learning JavaScript, which seems valuable if you want to do anything beyond a basic web page.
Please tell me if I'm missing something. I'd genuinely like to know.
I'm the lead developer on Volt. The goal here isn't to keep people from learning JS. I've been doing JS development since long before I found ruby. Just some thoughts on it I had been working on for a blog post:
In web development today, JavaScript gets to be the default language by virtue of being in the browser. JavaScript is a very good language, but it has a lot of warts. (See http://wtfjs.com/ for some great examples) Some of these can introduce bugs, others are just difficult to deal with. JavaScript was rushed to market quickly and standardized very quickly. Ruby was used by a small community for years while most of the kinks were worked out. Ruby also has some great concepts such as uniform access, mixin's, duck typing, and blocks to name a few. While many of these features can be implemented in JavaScript in userland, few are standardardized and the solutions are seldom eloquent.
Uniform access and duck typing provides us with the ability to make reactive objects that have the exact same interface as a normal object. This is a big win, nothing new to learn to do reactive programming.
--
Also, just as a side note, Opal does a great job of compiling ruby to JS. The code is easy to understand, supports source maps so chrome for example can bring up your ruby code in the console and show line numbers in the ruby code. While many gems won't work without some porting, a lot do. Opal currently runs rspec (a very complex ruby project) with only a few patches. Really though, typically front-end solutions do different things than backend solutions.
Cool-- thanks for the responses. I agree with the issues in JavaScript, but I'm not sure I see them as justifying a new web framework. For example, the Math.max() boolean behavior is simply the result of treating true and false as 1 and 0, which isn't unique to JS. Blocks are a type of closure (which JS supports) and there are ways to achieve multiple inheritance and even mixins as well.
That said, the larger point seems to be that data synchronization is the biggest benefit. If you can write a model once and have JS objects automatically created that'd be a good start. I'll have a look to see what other capabilities are there. The HTML rendering when a URL is called directly could be particularly powerful.
The interesting thing here is not that Ruby runs on both the client and server. The interesting thing is the client-server data synchronization, at least that was my perception having seen a talk on this a few months ago.
Yep I'd have to agree. While I'd rather use meteor for this task since it's native javascript on both ends, the killer feature for meteor is really the data binding across the client/server gap and not the ability to write js in both places.
You aren't completely alone a lot of people love Ruby and it's easy to see why. But it isn't the right tool for the job when you're talking about actions on the client, this has caused tension as client side development on the web has exploded.
There are many who wish to continue using Ruby.
I think people should take the opportunity to learn new tools like Meteor. Then come back when for example Ruby really can run client-side. Or with any luck a totally new language, something unlike Dart (which is just another javascript abstraction) comes along.
Dart isn't just another javascript abstraction. It has the option to compile into JavaScript, but so do many other independent languages, like Scala, Clojure and Haskell. It is its own language, with a VM, spec, an independent set of libraries, etc. This as opposed to for example CoffeeScript, which is purely (and intentionally) a JavaScript abstraction.
That said, my personal wish would be a language-agnostic virtual machine (or where the only "language" is that of the virtual machine itself) for the DOM, with a well-defined standard that could be implemented by different browsers. This would allow a lot of performance optimizations and remove the need for JavaScript to be a compile target. Instead, JavaScript would simply be one of a number of languages which target this VM.
You mean Java. The JVM was a way to safely run arbitrary code in a browser, write-once-run-anywhere. It was too early to come with DOM APIs to interact with the page around it, instead being like Flash in believing that the useful interactions would be inside the Java applet's window. But if we just took a headless JVM and gave it DOM APIs then problem solved.
I like Meteor, which seems to be similar except that Meteor also supplies a synced datastore (MongoDB on the server and a light weight equivalent in the browser).
I will definitely try this out, especially since I have already played with Opal (used in Volt).
Handling complex JSON documents is not easy with traditional sql databases like postgres and mysql. My team just got done building a large site with AngularJS, and using MongoDB (or any document store) allowed us an easy way of saving denormalized JSON documents. If you have a JSON object that contains an array of other objects, and each of those objects has arrays of other data, so you have a complex document that is 4 dimensions deep, with MongoDB (or any other document store) you simply put the document in the document store, but with MySQL or PostGre you would break that document up and store it in normal form, which means breaking it up into at least 4 database tables, maybe more. That is a lot more work and, crucially, that is much more likely to be impossible to automate. The code can not automatically know what deeply nested array of objects maps to some database table. The requirements for automatic normalization go beyond the features of your normal ORM.
There has been an explosion of these systems lately that automate the synchronization of frontend and backend. As far as I know, they all rely on document stores such as MongoDB.
Mongo may be the right call for your team, but just as an aside, the use case you're describing is perfectly doable with Postgresql using either text columns or json columns, and moreover, table denormalization is just as much of an option for relational users as for document store users.
"If the user hits a URL directly, the HTML will first be rendered on the server for faster load times and easier indexing by search engines."
If I'm understanding this right, it sounds like an incredibly cool feature. Being able to use the same templates for both server-side rendering and a client-side SPA-like experience would be a huge win.
I would like to reach a point in web programming where JS, or something that eventually compiles into JS doesn't have to be written or maintained explicitly. GWT comes to mind, and this does something similar with Ruby it seems. Interesting take for sure...
There's plenty of flavors of JS that compile into regular JS. Pair that with Node.js and you've pretty much got what you're asking for. There's plenty of people using CoffeeScript on server + client, for example.
Very interesting! I am interested in how data synchronization works. What data stores does the ORM currently support (my guess is mongodb so far)? How was it implemented? Would it work with multiple servers? I am not proficient in Ruby code, reading some code didn't give me a lot of information :)
hey, I do all sync stuff too, shoot me an email (you don't have yours listed in your profile), I have some pretty interesting solutions and I would like to compare notes.
Looking at this, it seems something that sits between the view (html) and the controller (data) would be needed. I understand the reactive html is used for now, but that would not work for complex UI interactions.
This reminds me of Lazo.js from Walmart labs (https://github.com/walmartlabs/lazojs). That is also a client-server framework with code shared between client and the server. Although Ruby is obviously harder to share, than JavaScript.
You realize it is walmart right? There is no bad word association. Any company the size of walmart, regardless of how you feel about their core business, is likely doing some cool things with technology.
LazoJS is quite nice. It is definitely more polished than RendrJS from AirBnB (equivalent framework for building SPAs that have fast first page load and are SEO-friendly).
Chris, I'm the main developer. So I haven't pushed much because I have been doing a big refactor on the reactive stuff and did get a little side tracked with some other stuff. The refactor is almost complete (400+ commits that should be out next week or the week after). From there there's just a few more things let and I think it will be ready for people to start building on. (After that I'll need to do a bunch of tutorials and videos)
Awesome, though why wait to push commits? Just put in a branch people can play with/watch until it's ready to merge to master or whatnot. Dunno if I'll have time but I'd love to play and see where it's going, much easier if latest stuff is online and visible :-)
Just idea of it, I like it. I am big fan of JS and think it has great future on both sides, but just on initial description of this, I really like it. I will try to give it a spin in next few days to have a more realistic experience. Thanks for making it.
Reading over the source on the example apps, the first thing that jumps out at me is _underscore _prefixed _variables and it just looks odd in ruby, especially with :_symbols
Yeah, it looks like a Python refugee's code or something. I also don't like the .cur name that you have to use everywhere. It's not descriptive enough by itself. I wonder why .value wasn't used as the obvious choice.
obsurveyor, I'm the lead developer. I've been doing ruby forever. The .cur is going to go away, along with .or and .and I'm in the middle of a big refactor of the reactive stuff to simplify all of that.
So the models in volt basically let you read and assign attributes with an _ We could use the model[:key] instead, but the nice thing with using _ is that you can then define your own getters and setters easily in the model class. The _ is sort of a quick prototyping tool, allowing you to start using attributes without defining them in the model. We're going to add it where you can say something like:
model_attr :field_name, String
then do:
model.field_name = 'something'
(without the _)
The _ keeps people from calling a method that isn't defined, since ._something will return nil if its not defined yet. But if you called .something, it will still raise an exception.
That sounds ripe for misuse and kind of schizophrenic with the different behavior based on the name of the attribute. You should pick one behavior(throw an exception) and apply it everywhere. If you want quick prototyping features, then make that something you include with a gem or something, don't let it infect the framework.
Handlebars/Mustache syntax is also widely used. And <% %> might very well confuse people into thinking the contents is raw code, as opposed to handlebar-style directives.
(Handlebars/Mustache restrict what actions you can take on view data substantially - you have to explicitly expose functionality in most implementations)
This thing would be million times more useful with Dart, which runs both in the frontend and the backend and is a stable language with some rich features. Still, a move in the direction though, I like it, but I think I'd never use this.