11 ms·
Why I switched from Ruby to Go
- PythonDeveloper 13y agoWow... looks like a couple of languages that want to be just like Python, but just... can't... quite... get there... :)
- joaomsa 13y agoOne approach I've seen for portable Ruby apps is to use JRuby. You gain the ability to package your code as a standalone, compiled java app for distribution. From that it becomes as simple as running 'java -jar app.jar' or use a similar transparent stub executable. Granted now you've just punted the problem of Ruby version to JVM version (which I've found to be less of a hassle) but at least took care of the nightmarish management of gem dependencies without something like bundler.
- alexatkeplar 13y agoThis x100. It's as simple as: $ gem install warbler -v 1.4.0.beta2 $ warble This creates a fat jar which is runnable with the JRE. It gets you out of RubyGems/Bundler/RVM hell.
- mcdougle 13y agoWow that's cool. I didn't even know that existed!
- jacques_chester 13y agoJRuby is an impressive piece of kit. Look at TorqueBox for a sequel.
- lloeki 13y agoSimilarly, while exclusive to OSX (and iOS, but that's out of the scope), RubyMotion produces native code. I wish the compiler were open source and could leverage, say, GNU's Objective-C runtime for portability.
- eliot_sykes 13y agotl;dr: Distributing command line apps is awkward when they are written in Ruby, so you're better off using Go. The author has created a library to help write CLI apps in Go [1] and gives an example of how to use it. [1] https://github.com/codegangsta/cli https://github.com/codegangsta/cli
- adrianoconnor 13y agoThe title of the post is "On Distributing Command Line Applications: Why I Switched From Ruby to Go", which changes the sentiment somewhat. The guy who wrote the post is clearly happy to choose the right tool for the job. The sensational title here looks silly. Anywaay Go looks like a good solution for what he's doing. I tried distributing a Ruby-based app years ago (maybe around 2008 or 2009) with a pre-compiled version of Ruby for Windows bundled as part of my programme. The Nullsoft installer package I wrote took ages to write all of those .rb files (that make up the standard lib). It sort of worked OK, but the project didn't go anywhere -- that was probably lucky -- it'd have been a nightmare to maintain.
- h2s 13y agoCouldn't agree more. I made the mistake of using Ruby to build a CLI application too, and distribution is a massive hassle. At the moment I'm still at the awkward stage of distribution via Rubygems which the article advises strongly against, and I'd add "Gem startup time cripples your performance" to the article's point about Rubygems being difficult for non-Rubyists.
- FooBarWidget 13y agoSo why don't you distribute your Ruby app without using RubyGems? Look, I've never been able to understand the people who think RubyGems is a good distribution mechanism for end users either. But switching to another language altogether seems to throwing out the baby with the bathwater. You can just create a Debian package or something that depends on Ruby. That's exactly what we do with Phusion Passenger. Have gem dependencies? Vendor them. Not that hard. But if you have gem dependencies that contain native extensions that aren't distributed by the OS... well then switching to Go starts to make sense.
- mcdougle 13y agoThat's assuming everyone's using Ubuntu (or some other Debian-based OS)... He actually did mention that in the post, though -- packaging Ruby into the installer -- and mentioned how difficult it is. I've never tried it myself, but I imagine it's pretty tough if, for example, you're distributing to Windows as well (although who uses CLI apps in Windows anymore...?)
- pjmlp 13y agoLots of us. Many configurations are done via command line tools actually, more so since PowerShell exists.
- vidarh 13y agoThe gem stat/open overhead really needs to be fixed. I have an application where rubygems causes about 35000 attempts at identifying the require'd files due to its horrific meddling with $LOAD_PATH. Whoever thought that was a good idea really did not think things true. EDIT: Strike that - I just realised one of my apps gets 117,000 ENOENTs from trying to handle require's during startup.... EDIT: I keep wanting to write something to cache the paths, but haven't had time. I'd be perfectly happy to be forced to regenerate cache on first run after any gem update. The 117,000 ENOENT's above comes from ending up with a $LOAD_PATH of about 100 entries, where the worst case causes almost every one of those directories to be checked for both foo.rb and foo.so. Something like 99%+ of startup time of most of my Ruby code is overhead added by rubygems way of handling require. EDIT: Actually, a lot of this might be down to bundler rather than rubygems in some cases. EDIT: This is not a robust solution, but this little ugly helper combined with wrapping only the two require statements shown, reduced the number of failed stat() calls for my app from 117,000 to 104,700 on startup... $orig_loadpath = $LOAD_PATH.dup require 'bundler/setup' $full_loadpath = $LOAD_PATH.dup def with_gems(*gems) filtered = [] gems.each do |gem| filtered.concat($full_loadpath.grep(/#{gem}/)) end $LOAD_PATH.clear $LOAD_PATH.concat($orig_loadpath) $LOAD_PATH.concat(filtered) yield $LOAD_PATH.clear $LOAD_PATH.concat($full_loadpath) end with_gems('require_relative') { require 'require_relative' if RUBY_VERSION =~ /1\.8/ } with_gems('amalgalite','arrayfields','fastercsv') { require 'amalgalite' } EDIT: Wrapped a handful more require statements with "with_gems". Down to 76,000 failed stat()'s... I should have done this before. EDIT: Yikes. 32,000...
- shortlived 13y agoHow come no mention of rb2exe and things of that nature? Are they not viable options? (Haven't used ruby in years but when I did above mentioned solution was the way to go)
- vidarh 13y agoThey may be viable options if you happen to use the right platform.
- steeve 13y agoSpeaking of distribution, cross compilation on Go is really, really easy and awesome. And for those who want to do cross compilation _with CGO_, it's definitely possible and I put a little tutorial to do it: https://gist.github.com/steeve/6905542 https://gist.github.com/steeve/6905542
- kitsune_ 13y agoI'm looking forward to all the "Why I switched from Go to XXX" posts in three years. Same thing will probably happen to node.js pretty soon. It has already been happening to MongoDB for quite some time. Go is currently in its hype phase. Some people seem to make a living by writing post-mortems. Why does everything always have to be the latest and greatest thing on earth? Can't we just institutionalize the hype cycle? Like fashion, minus the seasons? One big show every year where everyone can compare their dicks and then let's shut up about it until next year?
- TheHydroImpulse 13y agoWhile there was some hype about Node, it didn't turn out to be a fad. The ecosystem is thriving and not slowing down anytime soon, especially with 0.12 and then 1.0 coming quite soon. While I tried getting into Go, and initially didn't like it but wanted to like it. Seems like the more I read about it, the more I get into it, the less I like it. Which kinda sucks, Go seems like a powerful platform.
- octo_t 13y agopeople said/saying the same thing about ruby/RoR too. "While there was some hype about Rails, it didn't turn out to be a fad. The ecosystem is thriving and not slowing down anytime soon, especially with Ruby 2.0 and then Rails 4.0 coming quite soon." is a thing someone could have easily said on this site in January 2013.
- rtpg 13y agoIsn't this still pretty true? I've seen a lot of job offers for RoR (granted, when looking in Japan it might be biased). Just because it's not Java-sized doesn't mean the community isn't there.
- rpedela 13y agoYeah, but Node.js actually has a valid use-case: code that needs to be non-blocking. Most of the time, you want web servers to behave that way. Yes you can do that in other languages/frameworks, but Node.js is the only one with an ecosystem where most modules are also non-blocking by default. If you look at the languages/frameworks that have survived their initial hype, it is almost always ones where there is a use-case that the language/framework uniquely solves well. C/C++: Easier than most of the other low-level languages. Used when performance and/or memory management are critical: kernel, database, embedded system, etc. BASH: Dammit, I just need a script that executes five commands in a row! PYTHON: A scripting language that properly handles gigantic numbers and seamlessly integrates with R. The scientists love it! And the list goes on. Of course those languages have other use cases, but the point is that they all have at least one use case that they are the best at. However only time will tell if Node.js ends up being the non-blocking scripting language or something else will take its place.
- vidarh 13y agoI love Ruby, and use it a lot, but I have to agree with him about distribution. It's one of the reasons I am slowly plodding along on my ruby compiler (though at my current rate it's still a couple of years away from being useful) - I want static executables. If I wanted to distribute a Ruby app to non-Rubyists today, I'd likely end up packaging up the Ruby interpreter of my choice and all dependencies in a single archive rather than trust a sane environment on the users machine. And that obviously limits the type of situations you'd want to use it substantially. For my part it's not really an issue, because of what I'm using it for, though.
- solarexplorer 13y agoPrevious discussion: https://news.ycombinator.com/item?id=6083231 https://news.ycombinator.com/item?id=6083231
- dodyg 13y agoThis is why enterprise tends to be very conservative and stick to one or two platforms for decades. It's stupid to throw away your investments when your tech du jour ran out of its time.
- trailfox 13y agoI write all my web apps on Cobol, with formal specifications for every piece of code. This Java/.NET/javascript/Rails/Python thing is just a fad. Everyone will come round back to Cobol, wait and see. Mark my words...
- threeseed 13y agoI was thinking exactly the same thing. Makes you wonder if all the people dismissing everything as 'fads' even have jobs. Because I can't imagine anybody hiring someone in IT who is so proud to dismiss any new technologies not on merit but because it is somehow fashionable.
- dodyg 13y agoDon't hire anyone that is reckless with your IT investments.
- voyou 13y agoAnd how right you were to stick with COBOL; even the Ruby community are re-inventing it now: http://cukes.info/ http://cukes.info/
- vezzy-fnord 13y agoThis looks to me like literate programming gone totally wrong.
- tonyplee 13y agoIf it is not running in PDP11/Commondo64, I ain't using it.
- 13y ago
- 16s 13y agoThis is the same reason I re-wrote a lot of my Python code in C++ many years ago. Distributing one self-contained, statically linked executable just works and even the most clueless user can download and run it. But I still use a lot of Python and I'm sure this guy still uses a lot of Ruby. Everything has its place.
- vorbote 13y agoHmm... There is a basic misuse of terms here. The author uses the term "distributing applications" but he is actually talking about application deployment. Oh well, language evolves and most of the times becomes murkier. But I do agree. There is a in inherent higher barrier of entry when you force your users to install third-party libraries or even your deliverable from an outside ("fourth-party"?) distribution source. Be it ruby gems, CPAN, Pypy, cabal, whatever.
- masklinn 13y agoSo... wouldn't any language which allows building statically linked executable be suitable for TFA's issue[0]? Or even just a more reliable version of py2app or py2exe-style bundling? [0] Ada, OCaml, Haskell, Rust, ATS if you're really perverted?
- humanrebar 13y agoRust isn't stable enough for anything but alpha-level applications at the moment. But you're right that the blog author should elaborate on why he chose Go over all of the other compiled languages (and even dynamic languages with nice standalone packaging solutions).
- lloeki 13y agoAlthough not mentioned in the article I'd venture to say language design choices squarely aimed at solving distribution woes, like: - static linking only (unless you 1. use cgo and 2. dynamically link against a native lib) - trivial cross compiling (but no cgo)
- deleted 13y ago[deleted]
- code_scrapping 13y agoIf we put aside the ego-bashing and dick-measuring, the good side of hyping-out a technology would be to find it's limitations. So, the articles will slowly turn from "why X is great" to "I don't want to move to X because...", but the meta-message is that you get a survey of tool usage. Always look on a bright side of hype, tu-dum, tu-dum-tu-dum-tu-dum.
- deleted 13y ago[deleted]
- caiob 13y agodef hype_switch from_lang, to_lang 'Why I switched from #{from_lang} to #{to_lang}." end
- camus2 13y agolive by the hype , die by the hype. That and the fact that the ruby/rails community is full of egocentric hipsters that like to take a shot at each other,other languages, and say "f*ck" too often... The problem is now these hipsters are moving to nodejs so that community has exactly the same problem too. Go community,while little, is more like python's, mature,respectful(most of the time),that's important on the long run,to build a community around positive and cosntructive thinking. NodeJS will burn itself like rails if it goes on that way.
- gfodor 13y agoThis is a fun little narrative that's been constructed here, but I fail to see how it has anything to do with the ruby ecosystem I see from here, which is full of highly maintained, mature libraries at this point.
- evilduck 13y agoAs a Ruby guy, one thing off putting to me is that what appears to be "idiomatic Go" involves naming things as tersely as possible. Most Go code I look at has maybe-usefully named types or interfaces and then they usually go and assign them to something utterly meaningless like 't', 'vt' and so on. Go's official docs and standard libraries seem to reinforce this style choice, and most 3rd party code follows this general C++ style inspiration too. I know I can do what I like in code that I would write, but it seems like I'd be swimming against the current.
- film42 13y agoThis has a lot to do with Rob Pike's programming style, as you can see from the plan 9 source: https://github.com/cao-xx/plan-9/blob/master/sys/src/libregexp/regaux.c https://github.com/cao-xx/plan-9/blob/master/sys/src/librege...
- melvinmt 13y agoYeah, I went a bit overboard with this style in my first go package as well (http://github.com/melvinmt/gt http://github.com/melvinmt/gt) but now I just follow the convention that only variables that are defined in the function signature should have a single letter. Because due to the explicit type hinting, if you use elaborate variable names, you often end up with redundant naming like: database *Database. So db *Database looks a bit nicer in my opinion while it's still very clear what it is.
- asdasf 13y ago>involves naming things as tersely as possible. No it doesn't. It involves naming things appropriately. If you have a 4 line function that does something with a string, that string argument should be named "s". You aren't making it clearer by giving it a longer name. The length of a variable name is proportional to its scope.
- evilduck 13y agoI disagree. 's' has no meaning by itself, which means that you have to read all of the context surrounding 's' into your short term memory just to gain any understanding of the single line you may be interested in. That's slow and more work than necessary most of the time. Also, naming things is a habit and a style. Short variable naming leaks out of 4 line methods into any 40 and 400 line methods you may eventually write, and it leaks into the ABIs/APIs of your application. I've rarely seen any code that would use 's' appropriately in a 4 line method that wouldn't hesitate to use it everywhere else inappropriately.
- voodoomagicman 13y agodoes anyone know what the library he is using is in the example ruby code?
- deleted 13y ago[deleted]
- finishingmove 13y agoCode Gangsta (certified) !!! Fuck. Yeah.