<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>SiKaNrOnG.com Blog - The Dreddy Coder</title>
    <link>http://sikanrong.com/blog/list_no_ajax</link>
    <pubDate>Tue, 22 Jun 2010 06:45:00 GMT</pubDate>
    <description>Tales of Rails, Ajax, code, and other geekstuff..</description>
    <item>
      <title>Javascript: Prototype Recursive Merge</title>
      <link>http://sikanrong.com/blog/view/127</link>
      <description>&lt;p&gt;I searched all over the internet for a real recursive Object merge function in Javascript and found less than nothing. All I wanted was to find a piece of code to properly organize these sets of silverware...&lt;/p&gt;

&lt;pre&gt;
obj1 = {silverware:{fork: 1, spoon: 2}}; 
obj2 = {silverware:{fork: 3, spork: 4}};
&lt;/pre&gt;

&lt;p style='margin-top:10px'&gt;
So after a REAL recursive merge, I'm expecting to see this:
&lt;/p&gt;

&lt;pre&gt;
obj3 = {silverware:{fork: 3, spoon: 2, spork: 4}}; 
&lt;/pre&gt;

&lt;p style='margin-top:10px'&gt;
So, here's the method I wrote to do just that - it uses the Prototype Javascript framework though the basic techniques can surely be used without it...
&lt;/p&gt;

&lt;pre&gt;
function merge_recursive(obj1, obj2){

 obj1 = $H(obj1);
 obj2 = $H(obj2);

 var obj3 = obj1.clone();

 obj2.keys().each(function(key){
  if(typeof obj3.get(key) == &quot;undefined&quot;){
   obj3.set(key, obj2.get(key));
   }else{
    if(obj3.get(key).constructor == Object){
     obj3.set(key, merge_recursive(obj3.get(key), obj2.get(key)));
    }else{
     obj3.set(key, obj2.get(key));
    }
  }
 });

 return obj3;
}
&lt;/pre&gt;

&lt;p style='margin-top:10px'&gt;
...have fun with it! I hope this helps whomever (in the spirit of good community, and better code!)
&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/127</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>The last thing I ever bought from the iTunes Store...</title>
      <link>http://sikanrong.com/blog/view/126</link>
      <description>&lt;p&gt;&lt;img style=&quot;float: right;margin-left:10px; margin-bottom:10px;&quot; src=&quot;http://dl.dropbox.com/u/824953/site_photos/no_more_parades.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;300&quot; /&gt;Today I had the worst Apple experience I've ever had. See, usually I'm quite happy with Apple. Specifically, the iTunes music store. If I ever can't find a way to pirate what I'm looking for or otherwise not pay for it via the internet, I OCCASIONALLY would turn to the iTunes store. Today marked the last time I'll do so. Here's why...&lt;/p&gt;
 
&lt;p&gt;So, i use linux. You can install iTunes in wine but the store doesn't work, not to mention the whole process is kind of a bitch. So, instead i installed the newest version of iTunes in a virtual machine. I bought my album and it download three tracks, then got to &quot;Processing Track&quot; and just crashed. Tried again, next 3 tracks, same crash. Now none of those 6 tracks are showing up anywhere.&lt;/p&gt;
 
&lt;p&gt;&quot;No big deal&quot; i thought, since iTunes will always sync your purchased music anyway, right? Just a matter of firing up my mac, upgrading all it's crap, and then doing a sync. Simple.&lt;/p&gt;
 
&lt;p&gt;...WRONG. Not since a recent change in apple policy. Now you only get to download it ONCE. I actually had to call customer service who then had to send an email to iTunes to basically make the half of the album that is now missing re-available for download. The customer service rep said essentially you can only do this once.&lt;/p&gt;
 
&lt;p&gt;So that's it guys, if your computer crashes or for any other reason you lose the files, you're fucked. Someone in cupertino has to re-approve you dowload the music (if they feel like it), but the customer service rep made it pretty clear to me that usually you'll be expected to &lt;strong&gt;&lt;em&gt;buy it again.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;So, as a customer, I'd just like to say &lt;em&gt;&lt;strong&gt;FUCK YOU, APPLE&lt;/strong&gt;&lt;/em&gt; - you're doing it wrong and you goddamn know it. I give up.&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/126</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Look Ma, no CAPTCHA!</title>
      <link>http://sikanrong.com/blog/view/125</link>
      <description>&lt;p&gt;As you can see below, instead of a normal and completely annoying CAPTCHA form, I've got a javascript CAPTCHA. The way this is achieved is basically this:&lt;/p&gt;
&lt;pre&gt;
Event.observe(window, &quot;load&quot;, function(){
  cookie_jar = new CookieJar({expires:34000, path: '/'});
  comment_token = Math.floor(Math.random()*100000000000000);
            
  cookie_jar.put(&quot;comment_token&quot;, comment_token);
  if($(&quot;token_hidden&quot;)){
    $(&quot;token_hidden&quot;).value = comment_token;
  }
});
&lt;/pre&gt;

&lt;p style=&quot;margin-top:10px&quot;&gt;Basically, this sets a random number in the cookie, and then places that same number in the comment submission form. Basically, this just serves to prove that they (e.g. any potential spammers) are using JavaScript in a way that is non-automatable. On the server end you just have to compare the token_hidden input (located somewhere in your form) to the stored cookie version. I use the cookie jar script by Lalit Patel (2009) for the cookie interface. This site uses rails,and to compare the cookie str to the param one looks like:&lt;/p&gt;

&lt;pre&gt;
cookie_checks_out = (params[:token_hidden] and
  request.cookies[&quot;__CJ_comment_token&quot;] and
  params[:token_hidden].to_i == request.cookies[&quot;__CJ_comment_token&quot;].gsub(/[^0-9]/, &quot;&quot;).to_i)
&lt;/pre&gt;</description>
      <guid>http://sikanrong.com/blog/view/125</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>The state of COMET technologies in 2010</title>
      <link>http://sikanrong.com/blog/view/124</link>
      <description>&lt;div&gt;
  &lt;p&gt;
    &lt;img src=&quot;https://dl.dropbox.com/u/824953/site_photos/Final_Fantasy_VII_meteor_by_Tomas_vc.jpg&quot; style=&quot;float:right; width:200px; height:auto;&quot;&gt;
    So guys, welcome to the future! Happy 2010! Since we've already all got jetpacks and rocketcars, I guess writing about something as banal as persistent TCP connections to a webserver might seem like slow news. Oh wait, we don't have any of that shit? Well, on to the TCP sockets then!
  &lt;/p&gt;
  &lt;h3&gt;The Problem&lt;/h3&gt;
  &lt;p&gt;  
    The problem sums up pretty nicely. The web in its' current form suffers from a big fat fundamental problem in its' design. The problem is simply that the web as we know it is based on the concept that a web browser will send a request to a server, and the server will send (or &quot;serve&quot;) back the data. For a truly tremendous amount of tasks, this really works just fine.
  &lt;/p&gt;
  &lt;p&gt;
    However, the inability for the server to communicate with a browser without first requiring that browser to request something has in recent (and even not-so-recent) years become a large hinderance. The problem is easy to visualize thinking about web-chat. See, the problem is that in a chat-room, in theory, this is a very valid use-case:
  &lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;
      A user sends a message, which is received by the chat server
    &lt;/li&gt;
    &lt;li&gt;
      The chat server has to send that same message out to all users connected to that room.
    &lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;
    The problem lies in that 2nd part. It's easy for the browser to send the server the message, but it's impossible for the server to send the message back out to all the other users under the standard http model of the web.
  &lt;/p&gt;  
  &lt;p&gt;
    Under the standard old model, the only way for the other browsers connected to the webchat to get that message was to send out a request to the server telling it to update the chat. This is why in the 90's all web-chat applications relied on reloading an iframe of sorts, or other forms of polling the server. 
  &lt;/p&gt;  
  &lt;p&gt;
    It ends up that for a lot of reasons, this just plain does not work. In the case of chat, the reason why it breaks down is twofold: 
  &lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;
      Since messages can come in while the user is waiting for the browser to request a server update, the coherency of the conversation is easily lost.
    &lt;/li&gt;
    &lt;li&gt;
      This just does not scale. If there's 1000 users connected to your server, even if nobody has sent ANY messages, you're still going to get 1000 update requests for the server to process, at a rate of whatever the update interval is. Eventually the server will needlessly overload. Not good.
    &lt;/li&gt;
  &lt;/ol&gt;
  &lt;h3&gt;The Solution&lt;/h3&gt;
  &lt;p&gt;
    In comes COMET: a word which describes a series of techniques that web developers have designed throughout the years to circumvent this issue. Also, a set of more official techniques are currently being drafted through the W3C's standardization system for official inclusion in the HTML5 spec. Basically, in terms of code, it means you can do this:
   &lt;/p&gt;
&lt;pre style=&quot;margin-bottom:10px&quot;&gt;group_of_users.each do |user|
  user.browser.send(javascript)
end&lt;/pre&gt;
   &lt;p&gt;
    ..and it doesn't even have to be in the render or the template part, you can do it at *any* point in the request cycle. 
  &lt;/p&gt;
   &lt;p&gt;
    The first real comet technique is called the &quot;forever frame&quot; technique. All techniques (right now, in 2010) that use the browser to establish the connection (more about Flash later) work very similar to the forever-frame. Basically, the forever frame is a server-side hack that utilizes certain parts of the HTTP protocol to effectively send data from the server back to the browser without the need for a request. 
  &lt;/p&gt;
  &lt;p&gt;
    Technically, the long-and-short of it boils down to: an iframe hidden in the page sends a request to the server which the server nerver actually completes. Instead, what basically happens is that during this extended &quot;connection&quot; period (which never terminates) the server can &quot;hiccup&quot; little bits of data back down the pipeline to the iframe, which can then communicate with the parent page via Javascript/JSON! Easy as that!
  &lt;/p&gt;
  &lt;p&gt;
    More recently, Ajax connections have replaced the iframe, but generally the basis of the technique is the exact same: Open a connection, don't close it, use the HTTP protocol to hiccup back the data. While all this seems fine so far, the list of GOTCHA's associated with using COMET in all it's various forms (in 2010) is GIGANTIC. Just absolutely huge. This article will try to form a semi-complete (at least in-depth) list of these GOTCHAs such that developers struggling with them might be helped.
  &lt;/p&gt;
  &lt;h3&gt;The Connection Limit GOTCHA&lt;/h3&gt;
  &lt;p&gt;  
    Certainly the most prevalent GOTCHA is the dreaded browser connection limit. Normally this limit isn't *such* a huge deal on the web. That is, there's a lot on the web you can write without running into a wall that involves the connection limit. COMET, however, is not one of them. Each browser has an upper limit on the maximum number of simultaneous connections it can make to any given server. These are (for Mozilla and IE)
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Firefox has 8 in all recent or modern versions.&lt;/li&gt;
    &lt;li&gt;Internet Explorer 6.0 and 7.0 both only have two, which makes traditional COMET techniques just absolutely painful. More on this later..&lt;/li&gt;
    &lt;li&gt;Internet Explorer as of version 8.0 supports 6.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;
    Now, it is worth noting that using a simple CNAME hack it is *possible* to get around the 2-connection limit in IE versions less than 8.0. Note that when the connections run out, even normal page-loads to the server simply will not process until other connections are closed (making for an AWFUL user experience). However, the problems with internet explorer and connection limits don't stop there...
  &lt;/p&gt;
  &lt;h3&gt;The IE abort() GOTCHA&lt;/h3&gt;
  &lt;p&gt;
    Internet Explorer is fundamentally flawed in terms of COMET because of the way (in all versions) that the TCPSocket Javascript object is handled, specifically with regards to the &quot;abort&quot; method. Let me clarify...
  &lt;/p&gt;
  &lt;p&gt;
    So, basically this is how it is: all browsers work a lot with a low-level javascript API called &quot;TCPSocket&quot;. One of the methods specified by the W3C for this object is called &quot;abort&quot;. When you call the abort method, it's meant to terminate the open connection. Normally, this works pretty-much fine. The difference between how Mozilla and Microsoft handle this seems really small but makes all the difference.
  &lt;/p&gt;
  &lt;p&gt;	
    In Firefox, when abort is called, a notification of closure is sent off to the server and then (without waiting for any response) the active connection is nuked and removed from the active asynchronous connection count. This is how it should always happen.
  &lt;/p&gt;
  &lt;p&gt;
    On that note, it's no surprise that this is NOT what Microsoft does. On internet explorer, when &quot;abort&quot; is called, it will fire off a request to close the connection to the server and then it will NOT decrement the maximum active connections counter until it receives that response. The Catch22 of the whole thing is: if the maximum number of connections has been reached, how the hell is it going to send a message out to a server to tell it to close one?
  &lt;/p&gt;
  &lt;p&gt;
    The Microsoft answer to this is absolutely nothing. There is no answer to this, on IE, you're just fucked if you run into that use-case. ...and that's it. You can write your code really careful/cleverly, but there's no way (NO way) to 100% safeguard this situation from happening.
  &lt;/p&gt;
  &lt;h3&gt;Flash RTMP, a decent solution&lt;/h3&gt;
  &lt;p&gt;
    So, where internet explorer fails, Adobe (as usual) steps in, which leads me to talking about flash. See, most of the time using flash to open your sockets will just use the browser to do it, which means you'll still be hitting the connection limit wall. BUT, if you use Adobe's own &lt;a href=&quot;http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol&quot;&gt;RTMP&lt;/a&gt; (or RTMPS) protocol, suddenly you'll get to circumvent the browser's connection limit, as the necessary communication will take place from adobe's own flash process.
  &lt;/p&gt;
  &lt;p&gt;
    As a huge proponent for open-source in web technology, I was afraid of depending on a proprietary protocol for anything, especially as our entire app and stack is based on OS technologies and making any proprietary exceptions to that would really be asking a lot. That's why it's great to have something like &lt;a href=&quot;http://www.themidnightcoders.com/products/weborb-for-rails/overview.html&quot;&gt;WebORB&lt;/a&gt;, which is an easy, free, and open-source way to facilitate communication between an existing Rails, Java, ASP.net, or PHP application. However, while this does keep the server-side of things open-source, it still stipulates the use of flash (not OS) on the client side, so - that sucks. BUT, in 2010, flash is still more-than-widely used, and so it's still a pretty reliable choice and especially when considering the benefits of COMET in general, and the bugginess of the alternatives due to the unavoidable failure of abort(). 
  &lt;/p&gt;
  &lt;h3&gt;The W3C, WebSocket, COMET, and the future.&lt;/h3&gt;
  &lt;p&gt;
    So, lastly, I'd like to talk about the new WebSocket API which is currently being finalized by the W3C for the HTML5 specification. We should be expecting to see this quite soon, perhaps even in the next generation of major browsers like Internet Explorer 9.0 or Mozilla Firefox 4 (note none of this has been confirmed) yet. Basically, this is the W3C's official answer to comet, and will be used for bidirectional communication from client to server. I would 100% expect this to take care of he IE issues with abort(), the websocket object has a close() function and it would seem it's going to avoid ending up in close_wait limbo (in fact, there's a flag that you can check to see if it was closed cleanly or not, too). Secondly, I would expect either:
  &lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;
      The websocket will not count towards the global connection limit builtin to browsers.
    &lt;/li&gt;
    &lt;li&gt;
      OR, maybe the connection limit will just be higher for the next generation of browsers.
    &lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;
    Anyway, that about wraps it up! You can now consider yourself an expert in the pitfalls of COMET. But, the benefits are just obviously huge. being able to write something as cool as: 
    
  

    &lt;pre style=&quot;margin-bottom:10px&quot;&gt;user.browser.send(javascript)&lt;/pre&gt; 
    
&lt;/p&gt;
   &lt;p&gt;
    ...Straight from the server is something worth bending over backwards for!!
  &lt;/p&gt;
&lt;/div&gt;</description>
      <guid>http://sikanrong.com/blog/view/124</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Nautilus Effects: a proof-of-concept</title>
      <link>http://sikanrong.com/blog/view/123</link>
      <description>    &lt;object width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/OzBT3e6jt28&amp;hl=en_US&amp;fs=1&amp;&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/OzBT3e6jt28&amp;hl=en_US&amp;fs=1&amp;&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;480&quot; height=&quot;385&quot;&gt;&lt;/embed&gt;&lt;/object&gt;
    &lt;div style=&quot;padding-top:10px&quot;&gt;
       In terms of advancing user iterfaces, we've seen a lot from the Linux community recently. In terms of window management, Compiz/XGL is easily the most visually stunning and productive solution offered by any modern OS. However, now that the lowest level of the window system is tricked-out with OpenGL, there is loads of room for visual improvement within the apps themselves.
	&lt;br&gt;&lt;br&gt;
       This project is about doing just that. What I've basically done here is added a 4th view mode to Nautilus (the GNOME file browser). My fouth view (called &quot;effects&quot; mode) essentially replaces the central part of the filebrowsing experience with an OpenGL frame. As is pretty clearly seen, it draws a lot of inspiration from coolIris's &quot;PicLens&quot; Firefox addon, as the main goal is to make a large set of data more navegable, thus presenting more information in a more natural way.
	&lt;br&gt;&lt;br&gt;
       Ideally, (like compiz) eventually it would be fantastic to actually integrate openGL with the lower-level GNOME widget calls, such that you could render the wiget itself to an openGL buffer and rewire some animations in OGL from there as needed (see &lt;a href=&quot;http://www.youtube.com/watch?v=X8NoZ041RPA&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;). Obviously, this would yield a huge advantage in that the animations would be universal and every GTK-based program would automagically be much more visually impressive. 
	&lt;br&gt;&lt;br&gt;
       Insofar as my proof-of-concept, this is not really what I've done (*so far*, see below..). This was really a total deviation from the standard nautilus GTK-widget based filebrowsing. I will very likely never be able to finish it, but the code is freely available from here, and GPL'd, of course:
	&lt;br&gt;&lt;br&gt;
	&lt;b&gt;&lt;a href=&quot;http://github.com/sikanrong/Nautilus-OGL&quot; target=&quot;_blank&quot;&gt;http://github.com/sikanrong/Nautilus-OGL&lt;/a&gt;&lt;/b&gt;
       &lt;br&gt;&lt;br&gt;
       ...and so I hope it can be of help to someone! feel free to re-use any parts of it you want. I'm using pango/cairo to paint the sprite/label/icon data onto openGL textures, basically, and then rendering to a context provided by the GtkGLExt library. I have absolutely no time to finish this, but if I did, the plan was to (instead of rebuilding all this functionality from scratch), actually use the existing icon widgets that nautilus uses to represent files, as these would already carry all the GTK functionality they were written to have. Meaning, that openGL would simply be used as a rendering layer for existing GTK widgets. Hopefully after enough work we could incorporate the integration of using GTK widgets naturally with openGL into it's own lib (&quot;GTKGLWidgetSupport&quot;?). That lib could then be re-used in other apps to acheive similar goals. 
      &lt;br&gt;&lt;br&gt;
       Beyond just functionality though, the possibilities of awesome transitions and animations that you could theoretically come up with is just endless. I implore anybody to contribute! Am willing to make anybody that's interested a project admin.
    &lt;/div&gt;</description>
      <guid>http://sikanrong.com/blog/view/123</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>VLC linux and the spirit of Christmas</title>
      <link>http://sikanrong.com/blog/view/122</link>
      <description>&lt;p&gt;So I opened VLC today on my ubuntu 8.10 install, and at first I thought the icon was broken. The Ktorrent icon gets weird from time to time, so I figured it was the same bug.&lt;/p&gt;
&lt;p&gt;Upon giving it a closer look, to my surprise, I discovered that the normal orange VLC cone was wearing a christmas hat! Check it out!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/vlcxmas2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/vlcxmas1.png&quot; alt=&quot;&quot; width=&quot;287&quot; height=&quot;139&quot; /&gt;&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/122</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Rails Javascript Testing (unittest.js the right way)</title>
      <link>http://sikanrong.com/blog/view/118</link>
      <description>&lt;p&gt;Hey all! It's been awhile since I've written. I hope you guys find this helpful, because I couldn't find this anywhere else on the internet and it took me ages. So, I've been using the javascript_test plugin. You can install this plugin with the following command in your project root directory:&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;ruby script/plugin install javascript_test&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;mkdir test/javascript&lt;br /&gt;ln -s ../../vendor/plugins/javascript_test/assets/ test/javascript/assets&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;Now, what you'll find is by default all this does is set up a framework with which you can test your javascript libraries againt NEW markup, that YOU have to write. I found this highly unrealistic. Only VERY rarely is the javascript in a rails application going to be able to be accurately tested in a 'vaccuum', meaning that the DOM and the JS have everything to do with eachother. Also, you want to be able to test the effects of your rjs templates, most of which will have everything to do with your markup and your application server &lt;em&gt;running&lt;/em&gt;. So, I thought about this for a while, and came up with (what I think) is a pretty elegant solution.&lt;/p&gt;
 
&lt;p&gt;When you run your tests (which you can do with the following command):&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;rake test:javascripts&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;What happens is the javascript_test plugin initializes a new WEBrick server running on port 4177, and all it really does is provide some basic functionality to run the JS tests with your newly written markup. It has nothing to do with your application ruby code, nor can you access that code via AJAX requests. Crap, huh? So, clearly this needs to be improved upon, and I believe I've found a way. Basically what I'm doing is opening a new window with my application server running in it, and simply running the tests (and the assertions) using the dom and JS included by the app! Completely unobtrusive, and you get the full power of the application when you test the JS. However...&lt;/p&gt;
 
&lt;h3&gt;Issue: Same Origin Policy&lt;/h3&gt;
 
&lt;p&gt;Basically the first thing you're going to get screwed by is this, in all modern browsers, JS from within a parent window cannot access the DOM of the child window in any significant way. This is to prevent cross side scripting attacks, which would otherwise hijack your browser behind the scenes and post midget porn all over your facebook. Now, you wouldn't think it - but according to same-origin policy 'http://localhost:3000' and 'http://localhost:4711' are actually different domains (because of the port). Firefox 3 (and previous) don't even provide a way to temporarily disable this, so you have to exploit the single loophole in same-origin policy: subdomains. You're allowed to access the child window if it belongs to a subdomain of the parent window. So,&lt;/p&gt;
 
&lt;p&gt;&quot;How do I turn &lt;strong&gt;localhost:3000&lt;/strong&gt; and &lt;strong&gt;localhost:4711&lt;/strong&gt; into &lt;strong&gt;jstest.mysite.test&lt;/strong&gt; and &lt;strong&gt;mysite.test&lt;/strong&gt;??&quot;&lt;/p&gt;
 
&lt;h3&gt;Solution: Subverting Same Origin Policy via Apache&lt;/h3&gt;
 
&lt;p&gt;That's right! It is possible to use apache (with mod_proxy) and /etc/hosts to trick your browser into using the same origin subdomain loophole. I'm using apache 1.3 for this (Default on OSX Tiger), but it won't change too much for Leopard, or other versions of Apache in general.&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 1)&lt;/strong&gt; Uncomment these lines in the file /etc/httpd/httpd.conf (default OSX tiger file location)&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;#AddModule mod_proxy.c&lt;br /&gt;#LoadModule proxy_module&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; libexec/httpd/libproxy.so&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 2)&lt;/strong&gt; Add these sections to httpd.conf (replace mysite with whatever you want to use)&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServerName localhost&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ServerName mysite.test&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ProxyPass / http://localhost:3000/&lt;br /&gt;&amp;nbsp;&amp;nbsp; ProxyPassReverse / http://localhost:3000&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ServerName js_test.mysite.test&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; ProxyPass / http://localhost:4711/&lt;br /&gt;&amp;nbsp;&amp;nbsp; ProxyPassReverse / http://localhost:4711&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 3)&lt;/strong&gt; Add these two lines to /etc/hosts file&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;127.0.0.1&amp;nbsp;&amp;nbsp;&amp;nbsp; mysite.test&lt;br /&gt;127.0.0.1&amp;nbsp;&amp;nbsp;&amp;nbsp; js_test.&lt;/strong&gt;&lt;strong&gt;mysite.test&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 4)&lt;/strong&gt; restart Apache:&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;sudo apachectl restart&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 5) &lt;/strong&gt;Edit the file vendor/plugins/javascript_test/lib/javascript_test.rb, change line 176 to&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;browser.visit(&quot;http://js_test.mysite.test#{test}?resultsURL=http://js_test.mysite.test/results&amp;amp;t=&quot; + (&quot;%.6f&quot; % Time.now.to_f))&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 6)&lt;/strong&gt; Make sure you add this to your application layouts AND to the &amp;lt;head&amp;gt; tags of the files in test/javascript (NOTE: &lt;em style=&quot;color:#F00&quot;&gt;DO NOT LET THIS BIT OF CODE ONTO YOUR PRODUCTION SERVER&lt;/em&gt;). I've created a mechanism that I can turn on and off in environment.rb, a better solution would be to use arguements passed to script/server on rails start.&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.domain = &quot;mysite.test&quot;;&lt;br /&gt;&amp;lt;/script&amp;gt;&amp;nbsp; &lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Step 7)&lt;/strong&gt; Write tests that use your server! This is an example from one of mine - it opens the application in a separate window and logs in before doing other tests.&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;var &lt;/strong&gt;&lt;strong&gt;mysite_window&lt;/strong&gt;&lt;strong&gt; = null;&lt;br /&gt;&amp;nbsp; new Test.Unit.Runner({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; setup: function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mysite_window = window.open(&quot;http://mysite.test/login&quot;, &quot;mysite_window&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var execute_string = &quot;&quot;+&amp;lt;r&amp;gt;&amp;lt;![CDATA[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var inputs = &lt;/strong&gt;&lt;strong&gt;mysite_window&lt;/strong&gt;&lt;strong&gt;.document.forms[0].getElementsByTagName('input');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inputs[0].value = &quot;user@email.com&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inputs[1].value = &quot;password&quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;&lt;strong&gt;mysite_window&lt;/strong&gt;&lt;strong&gt;.document.forms[0].submit();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ]]&amp;gt;&amp;lt;/r&amp;gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setTimeout(execute_string, 2000);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; teardown: function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; testMysiteLogin: function() { with(this) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; wait(10000, function(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEqual(&lt;/strong&gt;&lt;strong&gt;mysite_window&lt;/strong&gt;&lt;strong&gt;.location, &quot;http://mysite.test/member-overview&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; }, {testLog: &quot;testlog&quot;});&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;Note that you don't have to have the window.open in the setup method, and in fact in most cases it's better if it just executes before the runner does (because it only needs to do so once). Anyway, You get the idea, now you can access all your JS methods from the window handler returned from window.open. So if I had a 'popup_cheesecake' function in my application JS, all I would have to do to test is is write something like:&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; testCheesecake: function() { with(this){ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //This Allows us to get the window handler of the popup without re-loading the URL&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var mysite_window = window.open(&quot;&quot;, &quot;mysite_window&quot;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assertEqual(&lt;/strong&gt;&lt;strong&gt;mysite_window&lt;/strong&gt;&lt;strong&gt;.popup_cheesecake()&lt;/strong&gt;&lt;strong&gt;, true);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }}&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;...And that's it! So anyway - I hope this has helped some people!! I know people on the rails scene have been looking into JS testing and seen solutions like the javascript_test plguin and shuddered in horror. This solution helps actually integrate the rails application AND the javascript testing suite, which in turn helps bring testing closer to what it's actually supposed to do - testing the software under real conditions!&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/118</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>How to convert a PHP guy to Ruby on Rails</title>
      <link>http://sikanrong.com/blog/view/117</link>
      <description>
 
&lt;p&gt;&lt;img src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/198px-Ruby_logosvg.png&quot; style=&quot;margin-left:10px; margin-bottom:10px; float:right&quot;&gt;Hey, this is something every ruby guy should know. If you're a contract worker you'll walk into a project sometimes and you'll find a management team that wants something more effective, and a staff that's stuck on what they know, just because they already know it. While people have a valid point that learning something new is hard, Ruby on Rails provides so many benefits to the development of a project that the learning curve is an acceptable loss of time. These are the things that stopped my dead in my tracks about ruby on rails development.&lt;/p&gt;
 &lt;ol&gt; 
&lt;li&gt;&lt;strong&gt;MVC&lt;/strong&gt; - If you're a PHP guy sitting there going &quot;What does 'MVC' mean?&quot; i don't blame you. The fact of the matter is, PHP is a fucking mess. Even highly touted web frameworks in PHP aren't really MVC based. MVC means Model-view-controller - and really it's the best way to construct a web application and keep the views separated from the logic code. Models in Ruby on Rails typically represent tables in the database, and lets you extend special properties to the objects if you want, while controllers use these model objects and organize them to put into the Views, which are the templetes.&lt;br&gt;&lt;br&gt;&lt;/li&gt;
 
&lt;li&gt;&lt;strong&gt;ActiveRecord&lt;/strong&gt; - if you know a PHP guy and you want to convert them into a rails evangelist - &lt;em&gt;show them ActiveRecord&lt;/em&gt;!! Since ruby is so object-based, ActiveRecord objects are directly related to the tables in the database. This means that you can &lt;em&gt;completely avoid writing sql&lt;/em&gt;. Now, if you're sitting there thinking &quot;But I already know how to write SQL, why would I do that?&quot; The answer is simple. What if you develop a site using MySQL and find out that your client's host is on Postgre? Well, in PHP you're fucked, and in ruby you have to change like one word, and everything works. Also, consider your site gets really popular and you find you'd like to switch to a different database for scalability reasons. Once again, on PHP you're fucked, and in Rails it's done for you. The real power here is being able to treat your DB tables like real objects. This means that if you have a table with geographic locations in latitude and longitude, you can easily extend that table's class with a 'country' method which returns what country the lat/longitute are in, and calling it is as simple as &lt;br&gt;&lt;br&gt;&lt;pre&gt;GeoCodes.find(id).country&lt;/pre&gt;&lt;br&gt; Which will find the object with the proper ID in the database and return the result of the find_country method. The php equivalent to this is MUCH more messy. Also, everything about the DB layer is handled by rails. This means that really complicated things are handled for you. What if you have two tables that are related? The type of tables you would do an INNER JOIN on in sql. In rails, if you've got one object and it's related to more objects in another table, getting to these other objects is as simple as a method call. Lets say that you have a people table in your DB and each person has many cakes, which are referenced from the cakes table. So, you need to get the person object: 
&lt;br&gt;&lt;br&gt;&lt;pre&gt;person = Person.find id&lt;/pre&gt;&lt;br&gt;Easy, right? Now you want to get their cakes: &lt;br&gt;&lt;br&gt;&lt;pre&gt;person.cakes&lt;/pre&gt;&lt;br&gt; Wow! ONE word?? Yes indeed. Now lets say you only want the cakes from this person with chocolate on them: &lt;br&gt;&lt;br&gt;&lt;pre&gt;person.cakes.select{|cake| cake.icing == &quot;chocolate&quot;}&lt;/pre&gt;&lt;br&gt; How about only chocolate cakes with less than 4 candles?&lt;br&gt;&lt;br&gt;&lt;pre&gt;person.cakes.select{|c| c.icing == &quot;chololate&quot; and c.candles &amp;lt; 4}&lt;/pre&gt;&lt;br&gt;...I believe I've made my point. In php (to say the least) ll this kind of stuff is painful and shitty to write, either because you're writing it in pure SQL and using PHP string operations to modify that sql, OR because you're doing it all on the PHP side with loops. Either way, it's messy and it's not as clean as this.&lt;br&gt;&lt;br&gt;&lt;/li&gt;
 
&lt;li&gt;&lt;strong&gt;Complete Ajax Integration - &lt;/strong&gt;Haven't you ever wished you could write client-side JS code from the server side, so you could consolidate all your logic code into one place? Well, I've often wished this using PHP, and what it comes down to is that you have to include JS into your templates and then carefully try to use the server output and the templates together to make some hoppin' AJAX goodies. You can also output ajax from php using strings and string manipulation techniques. Hooray.. In Rails, all of this is fully integrated. For example. You want to make an ajax call in rails that updates an element (let's say a news ticker) with a new random entry:
&lt;br&gt;&lt;br&gt;&lt;pre&gt;def update_ticker&lt;br /&gt; news_array = NewsItems.find :all&lt;br /&gt; rand_news = news_array[rand(news_array.length) ]&lt;br /&gt; render :update do |page|&lt;br /&gt;  page['id_update'].replace_html rand_news.body&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt; &lt;/pre&gt;&lt;br&gt;which will actually output the necessary cross-browser compatible javascript code to replace the html in the div with id=&quot;id_update&quot; with the body of the new random news item. All this without ever actually writing javascript. Pretty cool huh? &lt;br&gt;&lt;br&gt;&lt;/li&gt;
 
&lt;li&gt;&lt;strong&gt;Convention over Configuration&lt;/strong&gt; - This is important. Rails always assumes that whatever you're doing, you're trying to do it in the most common way that it's usually done. This means that it will assume that you're doing it in that common way, but if you'd like to change something about that (i.e. configuration) then you're free to do so. In PHP this is *not* the case. In php you're generally forced to point out every stupid detail of something before you use it, even if you're using it in the most common way it could be used. Examples? Lets say you have an action in your controller named hello_world. Rails will automatically look for your template for this action in views/controller_name/hello_world.rhtml, meaning that you don't have to write ANY code for it to understand that this is where that template is located, and try to use it when someone navigates to &quot;yoursite.com/controller_name/hello_world&quot;. However if you'd like to use a different template for your action you could always call &lt;br&gt;&lt;br&gt;&lt;pre&gt;render &quot;controller_name/different_template&quot;&lt;/pre&gt;&lt;br&gt;...or what if you want to render the hello_world template, but you want to render it in a different page layout than your site's default layout? No problem:&lt;br&gt;&lt;br&gt;&lt;pre&gt;render &quot;controller_name/hello_world&quot;, :layout=&amp;gt;&quot;different_layout&quot;&lt;/pre&gt;&lt;br&gt;Basically everything in rails acts like this: by default everything just works in the most common way possible, and if you'd like to add to it, you're free to. In php, nothing works until you make it work.&lt;br&gt;&lt;br&gt;&lt;/li&gt;
 
&lt;li&gt;&lt;strong&gt;Plugins&lt;/strong&gt; - Since rails is so well structured it's a very friendly framework to write plugins for. Say you've got users, and your users need to upload image attachments. Well, in php you have to write the image uploader, then you have to write the code that takes it from the tmp folder and stores it somewhere userful, and renames it, and checks that it's the right filetype, etc. In other words, in PHP there's 1,000,000 things you have to be aware of and configure so that your users can upload images. In Rails it's as simple as&lt;br&gt;&lt;br&gt;&lt;pre&gt;script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/&lt;br /&gt;&lt;/pre&gt;&lt;br&gt;After which you just specify that Users have attachments associated with them by putting this in the User.rb class:&lt;br&gt;&lt;br&gt;&lt;pre&gt;  has_attachment :content_type =&amp;gt; :image, &lt;br /&gt;                 :storage =&amp;gt; :file_system, &lt;br /&gt;                 :max_size =&amp;gt; 500.kilobytes,&lt;br /&gt;                 :resize_to =&amp;gt; '320x200&amp;gt;',&lt;br /&gt;                 :thumbnails =&amp;gt; { :thumb =&amp;gt; '100x100&amp;gt;' }&lt;br /&gt;&lt;/pre&gt;&lt;br&gt; WOAH! look at that! We just killed like 200 birds with one big line! You specify the max size (note also how sexy '.kilobytes' is), and even what size to resize the image to (and built-in thumbnail support!), just right there! If this could be easier, I'm not sure how. All of your image upload needs are basically taken care of for you by a 3rd party plugin for the framework, and it's fully customizable. You could attribute associated image information with any of your existing models (DB tables) in your app, in just about one line. &lt;br /&gt;&lt;/li&gt;
 &lt;/ol&gt; 
&lt;p&gt;Alright.. So there are really a WHOLE lot more items i could go off about, like &lt;strong&gt;blocks&lt;/strong&gt; and passing blocks, &lt;strong&gt;gems&lt;/strong&gt; and the incredible power they provide, &lt;strong&gt;database migrations&lt;/strong&gt;, or the built-in &lt;strong&gt;testing framework&lt;/strong&gt;, or the power of clean and easy URLs with &lt;strong&gt;routes.rb&lt;/strong&gt;, but I think the really core differences are the ones up there. Anyway, have a nice day! If you know any die-hard PHP people, feel free to make the web coding world a better place for everyone and show them this list!!&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/117</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Web 3.0: Caught with our pants down again?</title>
      <link>http://sikanrong.com/blog/view/116</link>
      <description>&lt;h3&gt;Web 1.0&lt;/h3&gt;
&lt;p&gt;Any respectable web expert can tell you that when the switch from web 1.0 to web 2.0 came about, a lot of people were caught with their pants down. The web 1.0 was like a giant library. If you were there, you remember it. It was like a load of people had been promised what we now know as &quot;Web 2.0&quot;, but the reality had fallen a bit short. The internet of the 90's was a place where there was undoubtedly a wealth of information, yet it wasn't really dynamic. Someone wrote it, you read it, and that was that.&lt;/p&gt;
&lt;h3&gt;Web 2.0&lt;/h3&gt;
&lt;p&gt;Suddenly, the paradigm shifted completely. Perhaps not *too* suddenly, but generally the web evolved from the &quot;Giant Library&quot; web 1.0 model and became something else entirely. The library was still there, but suddenly it was a place to hang out. It was a place to meet, and a place to interact with other people efficiently. In many cases, more efficiently than could be achieved by conventional means. This is our current model of the web. The web is &quot;Social&quot;. The web is a meeting place, and the content quite literally comes from all of us: the users. the following is an &quot;America Online&quot; ad from 1996, as you will see in the ad, none of the themes from &quot;Web 2.0&quot; or &quot;The social web&quot; are even touched on:&lt;/p&gt;

&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/xItCBJhKYwE&amp;hl=en&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/xItCBJhKYwE&amp;hl=en&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;br&gt;&lt;br&gt;
&lt;h3&gt;The Pre-Social Web&lt;/h3&gt;
&lt;p&gt;Holy crap I lost it watching that ad. It sounds like a Viagra commercial nowadays: &quot;My friends said I should try &lt;em&gt;The Internet&lt;/em&gt;, so i did!&quot;. Anyway I dug up the old AOL footage because really for a lot of Americans this is how we first got on the internet! As you can see in the commercial, the Web 1.0 was all about the endless supply of information that was available &lt;em&gt;to&lt;/em&gt; you. The angle was generally that the content was provided, and you were receiving it. The driving force of web 1.0 was commerce. Everything was basically a brochure that a user could browse through. It changed the way we thought about 'brick &amp; mortar' shops completely. The leaders of the web 1.0 world were sites that made the first attempts to consolidate the information of &quot;The Library&quot;. These were revered internet-superpowers like Yahoo, AltaVista, and Lycos, who were trying to figure up a good way to categorize and &lt;em&gt;index&lt;/em&gt; the information of the world wide web, and present it in such a way that your average user could navigate through it efficiently, a-la &quot;search engine&quot;. Even Geocities (remember!?) would make a lasting impression on the web by taking the very first steps into Web 2.0: giving users an easy portal to make their own webpages, and thus their own internet location. To that effect, geocities almost had the quality of being a 'Social' place, however it was more users just making new books for the library, rather than a true shift of paradigm. &lt;/p&gt;
&lt;h3&gt;What Web 2.0 Isn't, and what it is&lt;/h3&gt;
&lt;p&gt;
A whole load of people would say that web 2.0 has everything to do with &quot;glossy sleek designs, some easy non-contrasting colors, careful typography, and AJAX&quot;. While they are wrong, they're not entirely wrong. These things listed are simply a &lt;em&gt;sign of the times&lt;/em&gt;. These technologies are filling a lot of holes that previous ages of the web couldn't fill, and right now we're seeing them booming, but this does not characterize the heart of web 2.0. Web 2.0 is about user generated content. Thus, web 2.0 applications are about providing users a &lt;em&gt;means&lt;/em&gt; to 'get involved' in the web. A 'platform' from which they can easily meet certain needs, which are generally: 1) to easily be able to publish/create content, and 2) to publicize it. 
&lt;/p&gt;
&lt;h3&gt;Web 2.0, the Pre-Semantic Web??&lt;/h3&gt;
&lt;p&gt;So, if you remember the idea of geocities in 1996, they were web 2.0 pioneers, and they struck it really big with that, eventually getting acquired by Yahoo. Interesting right? In the age of &quot;The Library Web&quot;, the first ones in the race to &quot;The Social Web&quot; get the cheese. This is a very important point. I believe that this is what we're seeing right now. If you look at web 3.0 as &quot;The semantic web&quot;, this adds a whole new and not-totally-unexpected peice to the evolution puzzle. The term &quot;Semantic&quot; when used referencing web 3.0 generally conveys the idea that the barrier between computers and directly inputted human content will be much smaller, thus allowing computers to attribute relevance to content. Note that this is something largely impossible by today's standards. A computer can help you edit video, publish it, and publicize it - but for now all it knows about what's &lt;b&gt;inside&lt;/b&gt; the video are the words we humans attribute to it. So, the web 3.0 may mean quite a few things:&lt;/p&gt;

&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;It may mean the age of the incredible data mash-up, where micro-formats analogous to 'tagging' of internet content are used to hone in on content meaning and context.&lt;/li&gt;
&lt;li&gt;It may mean that finally we develop smarter software which can interpret data dynamically from a 'human' source, like a video camera, a spoken word, or even a photograph, and thus the computer can dynamically attribute context to such content&lt;/li&gt;
&lt;li&gt;It may mean that the graphics capability of the modern computer will shift so sharply that the very way we visually experience the web will be different, perhaps even a true end to a two-dimensional web&lt;/li&gt;
&lt;li&gt;It &lt;em&gt;will&lt;/em&gt; mean being able to depend on the internet to actually understand the context of your requests, and the ability for applications to &lt;em&gt;contextually&lt;/em&gt; infer data from other websites.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;h3&gt;Web 3.0: The future is smart!&lt;/h3&gt;
&lt;p&gt;It's very likely that it'll be a mix of all of those. So, as we've seen with the transition from 1.0 to 2.0, the leaders are usually the ones gunning for the next generation of features, first. Google (I believe) will be (already is?) one of the first pioneers into the web 3.0 world, as they are already introducing as much 'semantic' features into their applications as they can. Adsense (google's ad platform) mashes up useful ads against tag words and tries to place them in places where they 'fit' contextually. These first small steps towards web 3.0 have earned them millions. Let's take a hypothetical example. Lets say tomorrow flickr makes an announcement that in conjunction with BlahWhatever Corp they've developed an algorithm that can identify individual objects inside of a photograph. The entire internet would change. If you searched for the word &quot;Ball&quot; in flickr you would no longer get a picture with a ball in it, but instead you would get only the ball itself: the most semantically correct response for your search.&lt;p&gt;
&lt;h3&gt;Web 3.0: backwards-compatible?&lt;/h3&gt;
&lt;/p&gt;In another very different situation we have sites like facebook and myspace, which rely &lt;b&gt;heavily&lt;/b&gt; on the social aspects of web 2.0 to generate their content for them (their driving force). Now, with the advent of what's soon to come in 3.0, strictly web 2.0 companies won't necessarily be losing out, but it'll be a big &quot;Caught with your pants down&quot; moment, and perhaps even one that doesn't end so gracefully. After all, where are the superstars of web 1.0? What happened to america online's 1990's business model for &quot;The library of the world wide web&quot;? Well, not much, obviously - this is the kind of fate that I believe awaits the current empires of the social web. If you don't stay ahead of the curve, you fall behind it. It was a giant gap for developers to take an existing &quot;Read-only&quot; web 1.0 site and turn it into something social, and I imagine turning &quot;social&quot; into &quot;semantic&quot; won't be an easy task either. Not just for developers, mind you; when the whole paradigm of the internet shifts, your code &lt;em&gt;and&lt;/em&gt; your business model generally need to shift with it. This is the art of staying right on the bleeding edge, and not falling behind.&lt;/p&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;...So that's it. Just wanted to shed some thoughts about the future, because I think it's the most interesting topic there is. What I &lt;em&gt;don't&lt;/em&gt; need are 40,000 comments about how calling it web X.X is bullshit, and &quot;blah blah blah, stupid buzzword, blah blah, sells articles, blah&quot;. I don't fucking care; we're calling it web 2.0 because everyone is; it's here to stay. The next paradigm is already named web 3.0, because it makes sense. Deal with it.&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/116</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>MUR.DERLICIO.US LAUNCHED!! (testers needed)</title>
      <link>http://sikanrong.com/blog/view/115</link>
      <description>&lt;p&gt;&lt;a href=&quot;http://mur.derlicio.us&quot;&gt;&lt;img class=&quot;right border&quot; src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/86309.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;Hey all, have been writing this site for quite some (spare) time, and I couldn't be more proud of it. this site puts forth little competitions for ruby programmers!
It's basically a sandboxed testing environment, with a built in
rank/scoring system, so you can pit yourself agains other developers
(and even view their code and see how they beat you).&lt;/p&gt;
 
&lt;p&gt;Your uploaded
code gets evaluated by code length and execution time. I'm thinking
this will be fun for the ruby community! Anyway it's still in beta, but
now that I've got the basic framework down I plan on expanding it a lot
more. Any beta testers willing to give feedback would be appreciated.
Also, it's like a code-GAME! Who wouldn't want that?!?&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/115</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>2010: Knife-fight software development methodology</title>
      <link>http://sikanrong.com/blog/view/114</link>
      <description>&lt;p&gt;&lt;img style=&quot;padding:10px; float:right&quot; src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/dvd-dune-fight.jpg&quot; alt=&quot;&quot; /&gt;So, being a rails developer I often hear about &quot;Agile&quot; development methodology, and generally how developing a project given a certain set of guidelines will tremendously improve the quality of the final product. Well, I've got a methodology of my own. This is sure to replace Agile development and all it's avid followers. In fact, i see it springing up in Web 2.0 lingo everywhere around year 2010. Let me explain:&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;Knife fight software development model&lt;/strong&gt;&lt;/p&gt;
 &lt;ol&gt; 
&lt;li&gt;All disputes about the development of the project will be settled over knife-fight. This is the key element of the methodology.&lt;/li&gt;
 
&lt;li&gt;The project will be done in iterations, after which the lead engineer will have to systematically knife-fight each senior developer. This will determine the lead engineer for the next iteration of the project (as he will be the only one left alive).&lt;/li&gt;
 
&lt;li&gt;In the event of a dispute (namely between the designers and the programmers) an immediate knife-fight is required. The one left living will have their way in the issue. This helps prevent &quot;overlapping flows&quot; in the development cycle. &lt;br /&gt;&lt;/li&gt;
 
&lt;li&gt;Customers or users of the product should be frequently asked for their feedback. To adequately make a feature request in the knife-fight development model the customer must be asked to come directly to the office, where he or she will be confronted (again in a knife-fight) by one of the Jr. System administrators. Should The customer survive the meeting, the feature will be added to the next iteration.&lt;/li&gt;
 
&lt;li&gt;Adopting a new tool or technology requires that a representative of the company engages in a knife fight with the developer of the new tech in question. For example, if you were on a subversion system and someone suggests to move to git, the person suggesting the change would have to stand hand-to-hand combat with Linus Torvalds. We believe that this will help to confirm the seriousness of each request for tool-changes, as nobody would knife-fight linus torvalds unless they &lt;em&gt;really&lt;/em&gt; wanted to switch to git.&lt;/li&gt;
 &lt;/ol&gt; 
&lt;p&gt;&lt;img style=&quot;padding:10px; float:left; width:60%; height:60%;&quot; src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/knifefight.jpg&quot; alt=&quot;&quot; /&gt;So there you have it - I would suggest you start training your arm now if you're planning to develop software in 2010, as likely it's the only way you'll survive.&lt;/p&gt;
 
&lt;p&gt;...THE CAKE IS A LIE!!&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/114</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>How the internet went to hell in America (Part I)</title>
      <link>http://sikanrong.com/blog/view/113</link>
      <description>&lt;p&gt;&lt;img style=&quot;float:right; padding:10px&quot; src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/comcastic_blocktastic_slowtastic.jpg&quot; alt=&quot;&quot; /&gt;There's many forms of government in the world. Some are capitalist, communist, socialist... All have their downfalls. Nothing (*NOTHING*) fucks my day up more than when I hear some dumb american go &quot;Well, this is the best country in the world!! We've got &lt;em&gt;capitalism!&lt;/em&gt;&quot;&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;*SLAP!*&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;NO. No, no, no. Capitalism has it's downfalls too. Because of them, we're currently losing our right to a free and open and (un-corporate) internet. As ISPs clench their grasp on this, the internet has nothing to do but get worse (It'll be like &quot;Internet Vista&quot;). Basically - whenever people who want to make their pockets deeper really put their mind to it, the consumer inevitably has to bend over. The sort of insepid evil that's being talked about now is none other than (*CRINGE*) &lt;strong&gt;overage fees&lt;/strong&gt;. Now that net neutrality has been dealt some very real legal death-blows by the US 109th congress, the Senate, the House Judiciary Comitte, and notably &lt;em&gt;the Republicans,&lt;/em&gt; ISPs are now looking to fatten their wallots by charging users *OVERAGE FEES*. This means that there will be a cap on your internet. That's right, the same internet that you're paying for now, that one with no cap - you know that one? Well, in the bright and shining future of america, as our currency dwindles down to nothing, and our economy becomes stagnant, we're going to be paying the *SAME* amount of money, and then getting charged overage fees if we go over our data limit.&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&quot;WHAT THE FUCK&quot;&lt;/strong&gt;, right? &quot;What data limit?!?&quot; Right. First, how did something as evil as this happen? That's the real question, isn't it? If you direct your attention to wikipedia, you'll see the seven bills that have been proposed (and the five which have been denied) by congress. All of these bills attempted to make rules stricter for ISPs, and also to make sure ISPs can't limit our speeds on the internet based on limited-service packaging schemes (tiered service), or deny service to some websites, while allowing it to others. This is so that if large web entities like google one day wanted to become financially intertwined with an ISP, the ISP couldn't start &quot;coaxing&quot; people into only using google by blocking all other search websites. These are the rules laid out to keep the internet free, and to keep us (the consumers) free from getting financially bent-over by ISPs with huge amounts to gain at our expense.&lt;/p&gt;
 
&lt;p&gt;So, why did 5 of these bills get denied? One-word answer here: &lt;em&gt;MONEY&lt;/em&gt;. Which brings me to my point: &lt;strong&gt;Capitalism's inherent flaw is that some fish get too big, and start wildly eating all the other fish. They aren't playing the game anymore, they now are so powerful that they control the game.&lt;/strong&gt; This is what's happening in our country right now. They have the money to control the game, whether that be with lobbyists, with free lunches, and young guys with nice suits that wait by senator's parking spots... Sometimes, with coffee.&lt;/p&gt;
 
&lt;p&gt;So this is me, telling all of you whole hartedly, we're fucked. It's not really our fault, but rather the very nature of un-checked capitalism gone way out of control. Get ready for overage fees, americans, because they're coming your way to the tune of $1.50/GB, and caps as low as 5GB/month.&lt;/p&gt;
 
&lt;p&gt;..As a side note, Comcast is notably the absolute worst ISP available when it comes to pissing on our consumer rights. Not only are they actively filtering bittorrent traffic, although the protocol has plenty of legal uses, they are also among the first ISPs to consider (and implement) the software needed to constitute an &quot;Overage Charger&quot; and &quot;Data Transfer Limiter&quot;. Oh right, and did I mention they actually paid people right off the street to fill up the public hearings about net neutrality issues so that proponents for the legislation wouldn't have a place to sit? To any comcast employees reading this right now, &lt;strong&gt;please commit suicide to better the rest of our human experience.&lt;/strong&gt; ...Or just get another job, unless you're an executive of some sort. Then you're only option is really just to kill yourself. I figure you're so completly evil that anywhere you end up will make our lives worse somehow.&lt;/p&gt;
 
&lt;p&gt;What can you do to avoid this? Not a whole lot, honestly. Barack Obama has pledged that in his first year of office he will actively work with the FCC comissioner (also against net-neutrality) to try and set up stricter guidelines for ISPs, and subsequently make sure we can avoid shit like this. And by we I really mean mean all of &lt;em&gt;you&lt;/em&gt;, because if you're really smart (like me), you left the USA a long time ago with no plans on ever returning. Have a &lt;strong&gt;fucking comcastic&lt;/strong&gt; day, start saving up your cash so you have enough left to hand over to your ISP when the system fails you (again).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/113</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Which IDE (or editor) do you use?</title>
      <link>http://sikanrong.com/blog/view/112</link>
      <description>&lt;p&gt;Hey all, I tried to make a pretty complete list of all the IDEs in this poll, if I've left something out comment about it and I'll try to add it. What editor do you use? My vote's been cast (TextMate for the win!). I'm really curious as to how this'll turn out, just wrote the polling code today!&lt;/p&gt;

&lt;iframe src=&quot;/poll/display_poll_simple/1&quot; frameborder=0 style=&quot;width:500px; height:550px&quot;&gt;&lt;/iframe&gt;</description>
      <guid>http://sikanrong.com/blog/view/112</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>What anime people would really look like</title>
      <link>http://sikanrong.com/blog/view/111</link>
      <description>&lt;p&gt;My girlfriend tarrah just started using photoshop, and this picture made me piss myself! It's so amazing! Being an avid anime watcher, the first thing that popped in my head was &quot;Nyu???&quot;&lt;/p&gt;
 
&lt;p&gt;&lt;img src=&quot;http://i245.photobucket.com/albums/gg69/sikanrong101/bigeyes.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;...Those EYES!&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/111</guid>
      <author>Alexander Pilafian</author>
    </item>
    <item>
      <title>Jruby Applet: OpenGL running from Ruby in an Applet</title>
      <link>http://sikanrong.com/blog/view/110</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
 
&lt;p&gt;Hooray for combining technologies, this is a shining example of such work. So basically I've managed to put JRuby in an applet and make the ruby actually run the OpenGL code directly. I didn't want to bomb every visitor to this page with a java applet though, so I've made it a bit easier to deal with. If you want to see the applet in action, click &lt;a href=&quot;http://www.sikanrong.com/jruby_ogl_helloworld/sik-index.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. I've put this up on google code, so you can download the source &lt;a href=&quot;http://jruby-jogl-applet-launcher.googlecode.com/&quot;&gt;from them&lt;/a&gt;. Anyway - basically what I'm doing is making an applet, evaluating the ruby code specified by URL in the 'evalruby' parameter, instantiating a new Ruby class (in java) and using it. Specifically, the ruby file highlighted in evalruby must define the class 'RubyGLListener', which implements the interface javax.media.opengl.GLEventListener. Then you just 'plug' the GLEventListener into the applet's canvas and voila! OGL JRuby Applet Launcher, at your service!&lt;/p&gt;
 
&lt;p&gt;So here we basically have the hardest bit:&lt;/p&gt;
 &lt;pre&gt;package com.sikanrong;
import org.jruby.Ruby;
import org.jruby.javasupport.Java;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Block;
import org.jruby.runtime.GlobalVariable;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.RubyInstanceConfig;
import java.io.*;
import java.net.URL;

import java.util.*;
import javax.swing.JApplet;
import java.lang.ClassLoader;
import javax.media.opengl.GLEventListener;

public class RubyGLWrapper{


	public GLEventListener getGLListener(){
		return (GLEventListener) new Object();
	}

	public static RubyGLWrapper getInterfaceFromScript(String contents){
	   final Ruby runtime = Ruby.getDefaultInstance();
		
	   runtime.evalScriptlet(contents);

	   RubyGLWrapper ruby = null;
	   final IRubyObject rawRuby = 
                       runtime.evalScriptlet(&quot;RubyGLListener.new&quot;);	

	   ruby = (RubyGLWrapper) JavaEmbedUtils.rubyToJava(runtime, 
                          rawRuby, 
                          RubyGLWrapper.class);
           return ruby;
	}


}&lt;/pre&gt; 
&lt;p&gt;This is the RubyGLWrapper class - which is responsible for returning the Ruby class but wrapped so we can use it freely in java. Note the ruby class extends this class, and the only method we can call from java is getGLListener. If I wanted to call more Ruby methods from the java I would have to define the method both in the ruby and then a method to overwrite in the Java class that it inherits from. Moving on, this is the Ruby class:&lt;/p&gt;
 &lt;pre&gt;#!/usr/local/jruby/bin/jruby
require 'java'

include_class &quot;com.sikanrong.RubyGLWrapper&quot;

include_class &quot;javax.swing.JFrame&quot;
include_class &quot;java.awt.BorderLayout&quot;
include_class &quot;com.sun.opengl.util.Animator&quot;
include_class &quot;javax.media.opengl.GL&quot;
include_class &quot;javax.media.opengl.GLCanvas&quot;
include_class &quot;javax.media.opengl.GLCapabilities&quot;
include_class &quot;javax.media.opengl.GLAutoDrawable&quot;
include_class &quot;javax.media.opengl.GLDrawableFactory&quot;
include_class &quot;javax.media.opengl.GLEventListener&quot;
include_class &quot;com.sun.opengl.util.GLUT&quot;



class RubyGLListener &lt; RubyGLWrapper
  include GLEventListener
  def getGLListener
    self
  end
  

  
  def init(drawable)
     gl = drawable.getGL
    glut = GLUT.new

    gl.glShadeModel(GL::GL_SMOOTH);
    
    gl.glEnable(GL::GL_LIGHTING)
    gl.glEnable(GL::GL_LIGHT0)

    gl.glEnable(GL::GL_CULL_FACE)
  end
  
  def reshape(drawable, x, y, width, height)
  
  end

  def displayChanged(drawable, modeChanged, deviceChanged)
    
  end
  def display(drawable)
      gl = drawable.getGL();
      glut = GLUT.new
      gl.glRotated(0.15, 0, 1, 0);  
      gl.glRotated(0.15, 1, 1, 0);  
      gl.glClear(GL::GL_COLOR_BUFFER_BIT);
      gl.glColor4d(1,0,0,0);
      
      mat_specular = glFloatArray [1.0, 1.0, 1.0, 1.0]
      mat_shininess = glFloatArray [50.0]
      light_position = glFloatArray [1.0, 1.0, 1.0, 0.0]

      gl.glMaterialfv(GL::GL_FRONT, GL::GL_SPECULAR, mat_specular);  
      gl.glMaterialfv(GL::GL_FRONT, GL::GL_SHININESS, mat_shininess);
      gl.glLightfv(GL::GL_LIGHT0, GL::GL_POSITION, light_position);
      
      
      glut.glutSolidSphere 0.7, 20, 20
      gl.glFlush();
  end
  
  def glFloatArray(array)
    ret = java.nio.FloatBuffer.allocate(array.length)
    array.each do |n|
      ret.put(n)
    end
    ret
  end
  
end
&lt;/pre&gt; 
&lt;p&gt;..So elegant in it's simplicity... Note that the class inherits from the RubyGLWrapper and extends the GLEventListener interface. Pretty cool right? So as you can see all the OGL instructions in the applet are nicely contained right here in ruby! The possibilities with this stuff is endless, being able to manipulate OpenGL in ruby is going to lead to some awesome projects! Namely if those projects end up in an applet.. Speaking of which, this is the applet code:&lt;/p&gt;
 &lt;pre&gt;package com.sikanrong;
// External imports
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import com.sun.opengl.util.Animator;
import javax.media.opengl.GL;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;


public class RubyGLApplet extends Applet
{
	GLCapabilities caps;
	GLCanvas canvas;
	StringBuffer buf; 
	
    public RubyGLApplet()
    {

        setLayout(new BorderLayout());

        setSize(400, 400);

        setVisible(true);
	    caps = new GLCapabilities();
        caps.setDoubleBuffered(true);
        caps.setHardwareAccelerated(true);
	    canvas = new GLCanvas(caps);

        add(canvas, BorderLayout.CENTER);

        Animator anim = new Animator(canvas);
        anim.start();
    }
	public void init(){
		
                //ignore the weird spacing here
                //it's just to fit it into this 
                //page's formatting
		RubyGLWrapper ruby = RubyGLWrapper.getInterfaceFromScript(
                     readFileFromURL(
                        getParameter(&quot;evalruby&quot;)));

		GLEventListener listen = ruby.getGLListener();

        canvas.addGLEventListener(listen);

	}

	public String readFileFromURL(String strUrl){
	    String line;
	    URL url = null;
	    try{
	      url = new URL(strUrl);
	    }
	    catch(MalformedURLException e){}
		StringBuffer strBuff = null;
	    try{
	      InputStream in = url.openStream();
	      BufferedReader bf = new BufferedReader(new InputStreamReader(in));
	      strBuff = new StringBuffer();
	      while((line = bf.readLine()) != null){
	        strBuff.append(line + &quot;\n&quot;);
	      }

	    }
	    catch(IOException e){
	      e.printStackTrace();
	    }
		return new String(strBuff);
	}


}
&lt;/pre&gt; 
&lt;p&gt;Which is pretty short, note in the init method we grab the ruby eval url and instantiate the RubyGLWrapper instance, and from that we get the interface to pull our newly instantiated RubyGLListener out and use it for the applet canvas (i.e. we just 'plug' it in!)&lt;/p&gt;
 
&lt;p&gt;So, &lt;strong&gt;pitfalls and other points of interest&lt;/strong&gt;:&lt;/p&gt;
 &lt;ol&gt; 
&lt;li&gt;The jruby jar is HUGE and it makes the applet take forever to load. I've been nagging people on the JRuby forum to make a slimmed down build option for the JRuby jar to alleviate some of this, and I think soon they will&lt;/li&gt;
 
&lt;li&gt;I'm using the JNLP applet launcher to run this, which is awesome because it automatically downloads the native OGL stuff when needed for any OS/Architecture. That's freakin pimp, because it means that once you've written the Ruby OGL code, it's portable to any computer with a browser. Awesome!!&lt;/li&gt;
 
&lt;li&gt;I'd really like to use Pack200 too solve the size issue, and i just haven't been able to get it to work, anybody that could point me in a good direction should&lt;/li&gt;
 &lt;/ol&gt; 
&lt;p&gt;&lt;strong&gt;Where is this going?&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;Well the right answer is really &quot;Anywhere&quot;, but I'd really (*really*) like to make a 3d game-engine in JRuby that has applet portability capabilities. I'd like to do it in JRuby because it would provide freedom and a concise &amp;amp; clean way to write game code on a level that the world of game-programmers have never before seen. Think &quot;Ruby-on-Game-rails&quot;. I'm going to be incorporating the JBullet physics library - and seeing what cool syntatical stuff I can get ruby to do with significance to gaming (things like &quot;x = Model.new('/path/to/model.3ds', 'path/to/texture.jpg', :physics=&amp;gt;true)&quot;). Unfortunately that's all going to take forever because I'm really doing all this stuff on the weekend. Cool beans though, right??!&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&quot;So what does the applet actually do so far?&quot;&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;If you want to marvel in the fact that it works, sure, go ahead and give it a click. All it does though is show a spinning sphere with a light pointed at it rotating though, and after about 15 seconds it's pretty boring. The cool part is it's really acting as an applet Launcher for any ruby based OGL stuff, so if you just switch out the 'evalruby' file for another file, it'll use that OGL code instead. So, although my ruby only spins a sphere, you can download the applet jar and start writing your own Ruby OGL code and using the very same applet to run it, without actually even having to re-compile any java code. THAT'S slick.&lt;/p&gt;
 
&lt;p&gt;&lt;strong&gt;&quot;Your applet is broken&quot;&lt;/strong&gt;&lt;/p&gt;
 
&lt;p&gt;NO ITS NOT - it just takes forever-and-a-day to load, so sit back and forget about it, and one of these times when you check back it'll actually have loaded and be working. You have to hit 'Trust' when the little dialogs come up asking if you want to give my applet permissions and stuff.&lt;/p&gt;</description>
      <guid>http://sikanrong.com/blog/view/110</guid>
      <author>Alexander Pilafian</author>
    </item>
  </channel>
</rss>
