Hacker News new | past | comments | ask | show | jobs | submit login
Volt: A Ruby web framework where your Ruby runs on both server and client (github.com/voltrb)
279 points by senorgusto on Sept 15, 2014 | hide | past | favorite | 60 comments



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.


Just to make it explicit - Volt makes use of Opal.


So why not just use JavaScript to begin with?


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.


It can be better if it is compiled from a strongly-typed language. This gives benefits you'll never get from raw Javascript.


It has been my experience that JavaScript is a high level language.

In this particular case, Ruby is not being compiled to JavaScript but being transpired.


> 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.


This is the interesting bit for me personally:

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.


SignalR is not really baked into Asp.Net, it's only a gem (=Nuget Package) away though.


The persistent connection makes volt a promising alternative to meteor. I guess I can't run pry debugging sessions in the browsers javascript console?

Server generated Javascript has come a long way since it was introduced in Rails, abandoned and then reintroduced again with opal. DHH wrote about opal one year ago https://signalvnoise.com/posts/3697-server-generated-javascr...


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.

Thanks!


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).


One day later: I had time to try Volt, and I really like it.


Very cool! Would it be safe to say Volt is Ruby's Meteor?


Absolutely. I haven't contributed to Volt, but I've lived Meteor for the past year or so. Volt looks like an interesting option, to say the least.


Just out of curiosity, I noticed that mongo is used in all the demos, and seems to be the only DB supported.

Any thoughts on how or whether this would be support other backends like redis or more traditional sql databases like postgres and mysql?


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.


Wow, as someone who hates JS and loves the server-side, this looks really really cool. I might have to learn Ruby just to try this.


There was discussions last week of compiled C++ being used on the client side too:

https://news.ycombinator.com/item?id=8287700


"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.


This is the holy grail. Investigation begins...


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.


Clojure + Clojurescript come to mind as well.


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 :)

https://github.com/voltrb/volt/blob/master/lib/volt/models/p...

(edit: I probably need to note here that I contributed to a similar part of Meteor, that has data-sync to persistent storage too)


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.


I'm sure Walmart labs is no joke. I can't think of a worse word association though.


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).


Kind of funny that you selected a name so similar to Microsoft's attempt at doing the same with .NET: http://en.wikipedia.org/wiki/Microsoft_Live_Labs_Volta


Why is this "released" now? The projects seems to be semi-dead (only a couple bug fixes since last April) [1].

[1] https://github.com/voltrb/volt/commits/master


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 :-)


Cool. Thanks for answering here. Great project I will surely give it a try at some point.


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.


How does something like Phonegap / Apache Cordova fit in to VoltRB?


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.


Then why the _'s everywhere, ruby is snake case but I don't think I've ever seen anyone do :_foo => "bar" or _foo: "bar"


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.

Does all of that make since?


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.


This may be an ignorant question, but why not use the <% %> syntax popularized by ERB instead of { } for view bindings?


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)


I was just talking about wanting something like this the other day. Wow, this is great.


Sounds like rubish to me.


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: