Ruby己死?NodeJS能否取代Ruby?
By jmoses
我最近一直在使用nodejs,我跟我的小伙伴們一直在討論nodejs是否會最終取代Ruby。我認為評價一門語言的是否流行最重要的指標就是使用這門語言和框架開始新的項目的數量。
我認為一張基于gems的發布項目數量的圖表可以很好的解決我的問題。rubygems首頁上的就有最新的流行數據顯示,但是我對最近的一些數據非常地感興趣。我認為如果開發者向gems(不同版本)貢獻的代碼緩慢下降,那么這就表明了這門語言的就不怎么流行了。
拿數據說話
在簡單的搜索之后,我無法找到適合的數據去做成一張圖表。不過我抓取了一些網站并發現一些有意思的數據。我使用的是nodejs cheerio庫。gem的可執行文件給了我們一張清單,它告訴我們都有誰在跑gem。幸運的是每一個gem的主頁都是一個很漂亮的地址(url),比如:Rails的主頁是:http://rubygems.org/gems/rails
下面是我抓取用的源代碼:
var request = require('request'),
cheerio = require('cheerio'),
bytes = require('bytes'),
sys = require('sys'),
fs = require('fs'),
exec = require('child_process').exec;
console.log('program begin: ' + new Date());
fs.openSync('out.csv', 'w');
exec("gem list --remote", { maxBuffer: 20000*1024 }, processGems);
function processGems(error, stdout, stderr){
var gems = stdout.split("\n");
console.info('total gems parsed: ' + gems.length);
gems.forEach(function(gem){
gem = gem.substring(0, gem.indexOf(' '));
console.info('crawling gem: ' + gem);
request({
uri: 'https://rubygems.org/gems/' + gem,
}, getContent);
});
}
function parseSize(size){
size = size.replace(' ', '');
size = size.replace(/\)|\(/g, '');
size = size.toLowerCase();
try{
size = bytes(size);
}
catch(e){
console.error('unable to parse :' + size);
}
return size;
}
function escape(s){
if (s.indexOf('"') != -1) {
s = s.replace(/"/g, '""');
}
if (s.match(/"|,/)) {
s = '"' + s + '"';
}
return s;
}
function getContent(error, response, body){
if (error && response.statusCode != 200) {
console.error(error);
console.error(response);
return;
}
console.info(response.request.href + ' complete, status: ' + response.statusCode);
var $ = cheerio.load(body),
gem = $('div.title h2 a').text(),
latest = $('div.versions ol li').last(),
version = $(latest).children('a').text(),
date = $(latest).children('small').text(),
size = $(latest).children('span.size').text(),
line;
line = escape(gem) + ',' +
escape(version) + ',' +
escape(date) + ',' +
parseSize(size) + '\n';
fs.appendFile('out.csv', line);
}
整理數據
結果文件有2.7Mb,可以在這里下載,這不是可以做成圖表的數據源。我希望我的圖表y軸顯示當天發布程序的數量,x軸顯示發布日期。下面的一段nodejs可以整理之前的csv(數據)文件成我想要的格式。
var __ = require('lodash'),
moment = require('moment'),
csv = require('csv'),
fs = require('fs');
fs.openSync('releasedate.csv', 'w');
csv()
.from.path(__dirname+'/gems.csv', { delimiter: ',', escape: '"' })
.to.array( function(data){
var csv = '';
var grouped = __.groupBy(data, function(gem) {
return gem[2];
});
var array = []
for(var gem in grouped) {
array.push({
date: escape(gem),
unixtime: moment(gem, 'MMM D, YYYY').valueOf(),
released: grouped[gem].length
});
}
arraySorted = __.sortBy(array, 'unixtime');
arraySorted.forEach(function(gem){
csv += gem.date + ',' + gem.released + '\n';
});
fs.appendFile('releasedate.csv', csv);
} );
function escape(s){
if (s.indexOf('"') != -1) {
s = s.replace(/"/g, '""');
}
if (s.match(/"|,/)) {
s = '"' + s + '"';
}
return s;
}
用R繪制圖表
非常完美。現在開始繪圖了。我剛開始想用Excel,但是我發現我只能在一張圖上面創建255個點。這對于65K的數據文件來說是遠遠不夠的,所以我最終使用了R。下面的兩行代碼解釋了我為什么喜歡用R的原因:
data<-read.csv('releasedate.csv')
plot(zoo(data$Released,as.Date(data$Date,"%m/%d/%y")),xlab="Release Date",ylab="Releases",main="RubyGems Release Date Trend")
最終結果是我期望看到的一條曲線:

起我初驚呆了。這結果跟我之前預想的不太一樣,這張圖表顯示越來越多的開發者正在使用gems,我從這張圖表上面得到了三個結論:
1.Rubby的meetup組織有一大群虔誠的追隨者,并且有很強的領導力。
2.網上有非常多的關于Ruby的學習資源。
3.使用Rails創建網站非常非常容易。