I moved my blog to: http://macournoyer.com/blog.
New feed is at http://macournoyer.com/blog.atom
I know, I’m asking a lot… But I guarantee you’ll have a lot more fun if you update your feed to point to my new blog.
kthxbai
I moved my blog to: http://macournoyer.com/blog.
New feed is at http://macournoyer.com/blog.atom
I know, I’m asking a lot… But I guarantee you’ll have a lot more fun if you update your feed to point to my new blog.
kthxbai
Filed under Misc
Thin 1.0, codename That’s What She Said, is out!
gem install thin
Yes 1.0! That doesn’t mean it’s bug free or anything. But, it does mean that it’s been running on a number of servers and no show stopper bugs have been found since a while.
A lot of people have helped me achieve this milestone. I’m very proud to say that Thin is no longer my project, but the collaborative work of many bright people.
Here they are. If you like Thin or if it helped you in any way, please take a couple minutes and recommend them.
(If you contributed to Thin in any way and are not on the list, that’s an error so please let me know!)
Also thanks to everyone who’ve taken the risk to run Thin on their website.
Filed under Misc
I’ll be presenting Rack this Tuesday at the first Montreal Against Rails (the non-Rails meeting).
I’ll show how to use Rack and then I’d like to try something new (and probably crazy-stupid). Building a web framework with Rack is so easy, I’ll be doing pair programming with anyone from the audience to create our own custom framework live during the presentation (in 30 min). We’ll start with the code posted on RefactorMyCode as the application code, we’ll implement the framework code during the presentation. So submit your ideas there before the event.
To take part in first and biggest Montreal Ruby pair programming session and watch the other cool presentations, make sure to RSVP.
Filed under conference, montreal, ruby
Google Chrome looks cool, ok… But what is even cooler for me is V8, the super JavaScript VM.
JavaScript is a dynamic language, just like Ruby.
You can add stuff to objects at runtime, like Ruby.
It’s object oriented, like Ruby.
It has a GC, like Ruby.
…
What if we could run Ruby on V8?
Well, it’s a lot easier that you think. If you remember a while ago, someone released HotRuby. It runs YARV bytecode in the browser.
So I plugged the 2 together just to see what would happened => rbv8.
I used the script on HotRuby site to benchmark.
sum = "" 50000.times{ |e| sum += e.to_s }And just for fun, I also wrote it in C:
int main (int argc, char const *argv[]) { char *str = malloc(sizeof(char) * 238890); char buf[5]; size_t i; for (i = 0; i < 50000; ++i) { sprintf(buf, "%d", i); strcat(str, buf); } return 0; }Update: seems like my C code was the suck, thx for some commenters for pointing it out. Here’s a better version which is way faster (thx to Hongli Lai):
#include <stdio.h> #include <stdlib.h> #include <string.h> int main (int argc, char const *argv[]) { char *str = malloc(sizeof(char) * 238890); char buf[5]; size_t i; unsigned long last = 0; for (i = 0; i < 50000; ++i) { int len = sprintf(buf, "%d", i); memcpy(str + last, buf, len); last += len; } return 0; }Also here’s a Javascript version:
var sum = ""; for (var i = 0; i < 50000; i++) { sum += i.toString(); };C: 0.017 sec Javascript: 0.063 sec rbv8: 0.987 sec Firefox 3: 3.636 sec Safari 3: 4.368 sec Opera 9.50: 4.679 sec Ruby 1.8.6: 9.565 sec Ruby 1.9.0: 9.669 sec Rubinius 0.8.0: 15.576 sec JRuby 1.1 b1: 42.691 secOMG OMG OMG OMG!!! 10 times faster then YARV
and faster then C!Update: Ok… if your replace += w/ <<, YARV beats the Javascript version running on V8, thx to Nobu Nakada for noting this
But wait, don’t go tell your friends yet! It seems, that all the other benchmarks I tried were slower (sometimes by a very wide margin).
But I think this means that the potential is there, it just need to be exploited properly.
Also another fun thing to note, is that if you change Fixnum#times to while i < 50000 in the Ruby code, it becomes a lot slower. No idea why.
Me wants to try
If you wanna try rbv8:
You need Ruby 1.9 installed as `ruby19` and make sure you meet V8 Pre-requisites: http://code.google.com/apis/v8/build.html#pre_reqs.
git clone git://github.com/macournoyer/rbv8.git cd rbv8 rake bin/rbv8 sample/concat.rbNote that this is just a prototype. I just hacked this in an hour to benchmark it. See the README file for what needs to be done next.
Filed under ruby
>> Object.methods.size => 85 >> def i_is_in_ur_Object; "kthxbai" end => nil >> Object.methods.size => 86 >> String.new.i_is_in_ur_Object => "kthxbai"Careful what you put in there!
Filed under ruby
In Ruby, Class
is a Module
which, like any object, has a class.
>> Class.superclass => Module >> Module.class => ClassBut the crazy thing is, it’s the complete opposite in the implementation.
(Excerpt fromruby.h
)
typedef struct { VALUE super; struct st_table *iv_tbl; } rb_classext_t; struct RClass { struct RBasic basic; rb_classext_t *ptr; struct st_table *m_tbl; struct st_table *iv_index_tbl; }; #define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl) #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl) #define RCLASS_SUPER(c) (RCLASS(c)->ptr->super) #define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl) #define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m) #define RMODULE_M_TBL(m) RCLASS_M_TBL(m) #define RMODULE_SUPER(m) RCLASS_SUPER(m)We see it gets the instance variable table (
RMODULE_IV_TBL
) just like it’s a class. Modules are stored inRClass
structs.I know. I’m totally confused too.
You can now follow people on RefactorMyCode.com. Wow it’s like FaceBook + code snippets! Better get your mom an account!
You’ll then have a page with all stuff posted by your new friends and even an Atom feed.
To follow someone, simply go to their profile page and click on “Follow this user”.
Hope you like it!
Filed under refactormycode
require "rubygems";require "thin";require"markaby"; class Invisible
HTTP_METHODS =[:get,:post,:head,:put,:delete];attr_reader :request,
:response, :params; def initialize(&block); @actions =[]; @with=[];
@layouts={};@views={};@helpers=Module.new;@app=self; instance_eval(
&block) if block end; def action(method, route, &block); @actions<<
[method.to_s, build_route(@with*"/"+route),block] end;HTTP_METHODS.
each{|m|class_eval "def #{m}(r='/',&b); action('#{m}', r, &b) end"}
def with(route); @with.push(route);yield;@with.pop end; def render(
*args,&block);options=args.last.is_a?(Hash)?args.pop: {};@response.
status=options.delete(:status)||200;layout=@layouts[options.delete(
:layout)||:default];assigns={:request=>request,:response=>response,
:params=>params,:session=>session};content=args.last.is_a?(String)?
args.last : Markaby::Builder.new(assigns,@helpers, &(block||@views[
args.last] )).to_s ; content = Markaby::Builder.new( assigns.merge(
:content => content), @helpers, &layout).to_s if layout; @response.
headers.merge!(options);@response.body=content end;def layout(name=
:default, &block); @layouts[name]=block end; def view(name,&block);
@views[name]=block end; def helpers(&block);@helpers.instance_eval(
&block ) ; instance_eval(&block) end; def session; @request.env[
"rack.session"]end; def use(middleware, *args);@app=middleware.new(
@app,*args) end; def run(*args);Thin::Server.start(@app, *args) end
def call(env); @request = Rack::Request.new(env); @response =Rack::
Response.new; @params = @request.params; if action = recognize(env[
"PATH_INFO"], @params["_method"] ||env["REQUEST_METHOD"]); @params.
merge!(@path_params);action.last.call;@response.finish; else; [404,
{}, "Not found"]; end; end; def self.run(*args,&block);new(&block).
run(*args) end; def self.app;@app||=self.new end;def self.call(env)
@app.call(env) end; private; def build_route(route);pattern= route.
split("/").inject('\/*') { |r, s| r << (s[0] == ?: ? '(\w+)' : s) +
'\/*' } + '\/*';[/^#{pattern}$/i,route.scan(/\:(\w+)/).flatten] end
def recognize(url, method); method =method.to_s.downcase; @actions.
detect do |m,(pattern,keys),_| method==m&&@path_params=match_route(
pattern,keys,url)end;end;def match_route(pattern,keys,url);matches,
params=(url.match(pattern)||return)[1..-1],{};keys.each_with_index{
|key,i| params[key]=matches[i]};params;end;end; def method_missing(
method, *args, &block); ; if Invisible.app .respond_to?(method) ;
Invisible.app. send( method, *args, &block); else; super; end; end
Filed under ruby
Nick Sieger though us about Jazz, Giles Bowkett got a standing ovation, Zed Shaw sang “Matz can’t patch” and “Don’t fuck Chad’s community”, Geoffrey Grosenbach was wearing a kilt, Hampton Catlin presented Haml for Javascript, Damien Katz made me cry and Tom Preston-Werner is my new hero.
Filed under conference, ruby
Code is at http://github.com/macournoyer/meshu
Filed under conference, ruby, thin