Ruby on Rails 1.2.1 About to Drop?

Jan 19 ‘07

We were looking for the latest Rails Release Candidate to freeze into a aproject and ended up in Tags dir (http://dev.rubyonrails.org/browser/tags), and found this:

*rel_1-2-0 -- 5983 -- 9 hours --david: Fix nodoc breaking adapters (closes #7161) *rel_1-2-1 -- 5990 -- 3 hours -- david: Tagged Rails 1.2.1

So, it's hi-1.2-bye-1.2-hi-1.2.1?

Rails 1.2.1 About to Drop?

Jan 19 ‘07

We were looking for the latest Rails Release Candidate to freeze into a aproject and ended up in Tags dir (http://dev.rubyonrails.org/browser/tags), and found this:

*rel_1-2-0 -- 5983 -- 9 hours --david: Fix nodoc breaking adapters (closes #7161) *rel_1-2-1 -- 5990 -- 3 hours -- david: Tagged Rails 1.2.1

So, it's hi-1.2-bye-1.2-hi-1.2.1?

Sitemap Generator for Mephisto

Jan 14 ‘07

On the SEO front, there are a myriad of techniques for informing search engines about your site's content. One such technique is to generate a "sitemap". From Sitemaps.org, the new neutral 3rd party managing the format that that Google, Yahoo, and MSN have agreed to adopt:

Sitemaps are an easy way for webmasters to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site.

Check out an example here: http://40withegg.com/sitemap.

Anywho, I'll let you do your own research at Sitemaps.org and Google Webmaster Tools . I wrote a sitemap generator for the Mephisto blogs, such as this one. This code can be very easily modified for any Rails site by removing the references to Mephisto-specific constructs (such as @articles, @site, etc.).

Mephisto Sitemap Code


    module Mephisto
      class Routing
        def self.connect_with(map)
          # Allows access to the sitemap!
          map.connect    'sitemap', :controller => 'sitemap' 

          # Original code starts here.
          map.feed    'feed/*sections', :controller => 'feed', :action => 'feed'
          ... 

Trixy W3C Format

The only thing I had problems with was the lastmod date format used by the sitemap, which is W3c Datetime. For example:

<lastmod>2007-01-06T22:43:31-08:00</lastmod>

Particularly problematic was the Timezone information, which for me is Pacific, or 8:00 hours behind UTC/GMT, represented by the "-08:00" in lastmod. None of the Ruby, Rails, or TZinfo methods gave this format to me in one call. Here's what I tried:

  • article.updated_at.strftime('%Y-%m-%dT%H:%M:%S%Z') -- produced "2007-01-09T22:54:28Pacific Standard Time"
  • article.updated_at.xmlschema -- produced "2007-01-09T22:54:28Z"

Here's what I ended up doing:

time_zone = TimeZone.new(@site.timezone.current_period.utc_offset)
... 
xml.lastmod(article.updated_at.strftime("%Y-%m-%dT%H:%M:%S#{time_zone.formatted_offset}"))

Modify and improve it at will!

Floss your Teeth, Put on Sunscreen, and use an Ergonomic Keyboard

Jan 13 ‘07

How's this for a New Year's resolution: Get in shape! Nope. Eat healthier! Nada. Call my grandma more often! Well, yes, but that's not the point. Here it is:

Switch to a super-ergonomic keyboard.

Most geeks know that repetitive stress injuries (RSI) are a big risk for us, especially software developers who literally type and type and click and click all the live long day. But recently it has dawned on me just how big a risk it is: more and more developers at our small consulting company have RSI problems, ranging from minor annoyances to complete debilitation.

Yo, P: Yes, I'm talking about you.

On Monday, a fellow developer had to stop typing for the week, doctor's orders. And for a coder, that's an issue, since coding-by-thought technology is seriously lacking. This caused me to do some quick RSI-inflicted-peeps math:

  • We have about 20 people in our office:
  • At least 6 have RSI problems that I know of, which means there might be more.
  • 1 has been under doctor's orders not to type for the last year, and another has been told to keep of the keyboard all week.

These folk's ages are, as far as I can remember: early 40s, 39, 34, 32, 27 (no typing!), 23 (no typing!).

23? 27? Oh crap.

I'm 31 years old.

Kinesis Contoured Keyboard

Right now, I have no wrist, arm, or hand problems, save for the psychosemantic tingling I feel right now, but I've decided not to mess around with my software ditch-digging tools. Quite a few people I know swear by the Kinesis Contoured Keyboard, which is a pretty crazy looking device, but is optimized to baby your hands. I'm not looking forward to learning a new key layout, but I'll deal.

Now that kids are growing up in the Internet age, maybe parents will ad a new nag to their arsenal: floss your teeth, put on sunscreen, and use an ergo keyboard.

As a side note, since we practice pair programming at our office, we can absorb RSI-inflicted developers since they don't have RSI-of-the-brain.

Forwarding Agile Reality Traffic to Here

Jan 9 ‘07

Update: I'm going to us the same RedirectPermanent technique to redirect Agile Reality's RSS feed to here.

I've started forwarding the "popular" links from my old blog, Agile Reality to here. Pretty soon I'll forward the RSS feed, too. Since my 1and1 account uses Apache, I've added RedirectPermanent declarations to the .htaccess file in the web root dir.

For example:

For the popular "Visual Studio, Ruby on Rails, and Old Dudes Who Know Smalltalk" post (that is, more than one hit per day), I've added the following to .htaccess:

RedirectPermanent /2006/05/visual-studio-ruby-on-rails-and-old.html http://40withegg.com/2007/1/5/visual-studio-ruby-on-rails-and-old-dudes-who-know-smalltalk

A Summary of "Why is there no Smalltalk [or Java]-like IDE for Ruby"

Jan 4 ‘07

NOTE: You might have been redirected here. Don't worry! I've moved my active blog to 40. (with egg)

UPDATE: fixed my bad code...

Here follows my summary of "Why there is no Smalltalk-like [or Java-like] IDE for Ruby," compiled from the over 100 responses the threads on comp.lang.ruby and comp.lang.smalltalk,and the email thread on the Ruby on Rails mailing list . I will do my best not to bodge everything up. Interestingly, many comments on the newsgroups and most of the mailing list revolved around the IDEs are Good vs IDEs are Evil debate, which I might summarize at a later time.

I'll do my best with this! Be gentle.

Code Completion, Refactoring, etc.

It seems that the difficulty of Ruby code completion, refactoring,and pretty much every issue can be summed up as this: Ruby has no abuild-in concept of a live runtime "image" at development time, nostatic typing and method argument/return typing that clearly defines objects and methods, and no compiled artifacts that can be mined for data.

Smalltalk vs. Java

In a very, very small nutshell:

Smalltalk, like Ruby, is loosely-typed and (some say) compiled at runtime, but "runtime" is always happening. Smalltalk is alwayslive, always in a particular state at development time; the concept of"runtime" rather melts away, as there is nothing to really contrastagainst it. The state of the entire Smalltalk environment is saved in an ever-evolving "image" that can be mined for ample data to perform refactorings, code completion, and such.

Java, unlike Ruby, is a compiled, statically typed language, and these two features give an IDE ample data about Java objects at development time.

Challenge #1: Language differences between Ruby and Smalltalk

Ruby and Smalltalk are different beasts, even though they share many language constructs and philosophies, most notably loose typing, blocks, and the ability to "reopen" classes and instances at runtime to add methods, etc. But Smalltalk knows about it's development environment (link):

The Smalltalk language 'knows about' its development environment at quite a deep level. The fact that Ruby does not have any built-in knowledge of an environment makes it relatively hard work to make the language work 'seamlessly' in an IDE - I speak as someone who is trying to do just that :)

In other words, Smalltalk is tightly coupled to it's development environment. Smalltalk IDEs keep track of the state of things by keeping a constantly-evolving "image" of the code, which contains an enormously amount of metadata about the state of classes, methods, etc. For example, take the following example Ruby code, which changes a class named Shoe if a condition is met:

class Shoe
...
end

class ShoeTweaker
   def tweak_shoe
      if (self.i_feel_like_it)
         class << Shoe
            def laces #reopen class Shoe and change it!
               ...
            end
         end
      end
   end
end

If this code were saved in a Smalltalk-like IDE, this possible manipulation of the Shoe class would be stored in an "image", and the IDE (and the Smalltalk runtime environment itself) would forevermore know about this possible change to Shoe. Obviously, Ruby has no such facility built into the language itself. But, as pointed out in in the newsgroup thread, there is nothing preventing an IDE maker from providing this functionality (link):

... [In Smalltalk] methods and classes are /always/ added at runtime -- just as in Ruby.

The difference is that Smalltalk doesn't initialize itself by reading and executing a sequence of class- and method-creation expressions. The definitions already existed when your restarted your image. If you define new classes or methods, /then/ these are compiled at runtime and added to the image, so that if you save the image, |they will be saved too.

It makes Smalltalk /look/ as if it's like (say) C++ -- with a list of classes and methods which "just exist" and you browse over them in the IDE.... It would certainly be possible to create something similar for Ruby, but first it would have to have some way of preserving the state of the /entire/ computation between runs.

Hmm... an image-saving IDE would get around Ruby's interpreted nature, a very common theme pointing to why it's so hard to create a good IDE for Ruby. In Ruby, there are no compiled files or bytecodes to mine for metadata about Classes. The entire object tree is recreated as the script is executed. That said, the ruby Interactive Ruby Shell (irb) gets around this somehow, and if the irb's state could be saved, or always running, or if the editor in an IDE was the irb... This might be a great opportunity to implement a Smalltalk-like image/model paradigm for a Ruby IDE, but not make the same mistake choice :) that Smalltalk made to tightly couple the development image to the language and runtime itself. This might even be better (link):

... there are positive points about decoupling the programming from the environment. ... it is quite possible to introduce behavior that may have seemed neat this time last week but does not seem anything like as good now...

Challenge #2: Language differences between Ruby and Java

This one seems pretty easy to understand:

  • Ruby is loosely-typed, while Java is statically-typed
  • Ruby is interpreted at runtime while Java is compiled

As for the compiled-nature issue, reference the previously written stuff about Smalltalk images for info about how Smalltalk got around this. But, there are some interesting details about how Java IDEs have an advantage (link):

... In Java the IDEs use the front end of a compiler to build an abstract model of your program. The refactorings are actually applied to the model in a provably correct way, and then the changes are reflected back in the code. Having things like method generators, method_missing and dynamic structs makes this impossible to do without being inside a running program that can be inspected, which just won't work for a ruby IDE unless you turn it into a live memory type environment.

Java's statically-typed nature makes the world a relatively easy place to live in for IDEs: A class has X methods, implements Y interfaces, and inherits from Z classes. Method signatures are typed as well: in Java, lookUpNames(List names) takes an object of type List, while Ruby's look_up_names(names) takes... who knows? As long as that object don't blow up if messages are sent to it later, then we're happy. This makes code completion a little hard. Nobody had an easy answer for this (or even addressed it) but I'm sure there are some brute-force ways of implementing this, such as "guessing" Classes, or having the developer pick the Class once and remember it, or simply remembering a linked-list of method calls ('person' was once followed by 'name' and also by 'address', so those will be in the list of possible method calls...)

I'm sure I'm leaving stuff out, and if there are glairing mistakes I'll update this later. Hopefully those who were confused (like me) about why Ruby IDE development is so hard will find this useful.

1 Comments (from old blog):

At 10/29/2006 9:57 PM, Chad Woolley said…

There was a thread I saw recently where someone proposed that the unit tests could be leveraged to help exercise code in the IDE, and help determine the dynamic runtime state of the program. This is interesting, but even with 100% code coverage, you still couldn't ensure that every logic path through your program is covered (Unlike EMMA for java, which does block-level coverage metrics, rcov still only does line-level, and even that imperfectly).

Also, it seems like it would help a lot if IDEs were smart enough to find the areas where dynamic code might cause problems with refactoring (instance_eval, method_missing, etc), and either attempt to automatically handle them, or at least point them out to you and let you handle them.

-- Chad

Why is there no Smalltalk-like IDE for Ruby? - Update 1

Jan 4 ‘07

Tramendus response to my posts to the newsgroups and mailing lists! As of this writing:

I'll be combiling a list of interesting items soon, but overall themes include:

  • Smalltalk "knows" about it's development environment, helping it overcome a lot of issues that Ruby has.
  • Java is combiled + statically typed, helping it overcome issues that Ruby has.
  • Smalltalk and Java have funded projects and are supported by the business community.
  • That said, most of the issues can be overcome in time.
  • Update: people are passionate about their favorite text editors.
  • Update: the "we don't need IDEs" vs. "IDEs are almost essential" debate rages on.

Why is there no Smalltalk-like IDE for Ruby?

Jan 4 ‘07

I finally did it: I posted my "Smalltalkers and Rubyists unite for IDE support!" post to comp.lang.ruby, comp.lang.smalltalk, ruby-talk@ruby-lang.org, and rails@lists.rubyonrails.org. We'll see if I get trounced by the communities.

Hi all --

I shout my question to the entire Ruby + Smalltalk community: Smalltalk has had amazing IDEs for decades, why not Ruby? Smalltalkers, Ruby needs your help!

I'm hoping to start a centralized discussion about this topic, since my searches have only turned up scattered comments.

Ruby should have IDE support approaching Smalltalk's based on the following gross generalization: Ruby and Smalltalk are pretty much the same. Yes, I know there are many differences, and not trying to provoke a Ruby vs. Smalltalk cage-match, but based on language features and constructs, they are very similar.

What is holding Ruby back? How has Smalltalk overcome the issues? What can Ruby tool builders (such as the RadRails folks and, hopefully, me) learn from the Smalltalk IDE builders? Reasons I've heard for Ruby's lack of tool support include:

  • Ruby is not a compiled language
  • Ruby does not execute in a VM or run-time
  • Ruby is a loosely-typed language and has blocks, etc.
  • Nobody really cares enough about a Ruby IDE tomake one
  • vi is all you need!

Regarding the compiled language and VM arguments: what about Ruby's irb? Regarding loose typing, blocks, etc: Smalltalk has these! I don't pretend to understand all of the issues, but I want to learn. Unless there is something I simply don't "get", it seems that the Ruby community does not care or see the benefit of real tool support, which leads me to believe that (again) the Smalltalk community is not very interested in Ruby.

I've only been working with Ruby for 8 months after 7 years of Java, but I almost feel like a Smalltalker by association, having worked with, and for, Old Dudes Who Know Smalltalk (yes, I said it) my entire career. I've stepped back into the stone age regarding IDE support after using VisualAge for Java, Eclipse, and InilliJ IDEA. No refactoring, no fast debugger support, not even code-completion/suggestion. To the current tools, Ruby is text to colorize.

Smalltalkers, you've cracked this nut years ago, help us understand how to do it again in Ruby!

-- Joe

http://www.josephmoore.net/

Rails Cookies Mangles the Hash Interface

Jan 4 ‘07

Pop quiz: your browsing some ruby code (which you often do in your spare time) and see the following:

    party_like[:its] = "1999"
    puts party_like[:its]

What will be put to the console when these lines of ruby execute? You might be saying that since party_like seems to be some kind of Hash or a Hash-like-thingie, you should get...

    #=> 1999

At least 99% of the time you'd be right, unless the code is actually the cookies method in a Rails Controller:

    cookies[:its] = "1999"
    puts cookies[:its]

    #=> nil

BUWAHHHHHH? Cookies isn't a Hash, although the cookies method does return a CookieJar object, which extends Hash. CookieJar mangles the expected Hash methods of [] and []= with these gotchas:

  • The CookieJar object does not represent one set of cookies, it represents 2 sets: the incoming cookies from the browser, and the outgoing cookies that will be sent back to the client
  • cookies[:key]gets you the incoming cookies from the client
  • cookies[:key]= value sets outgoing cookies that will be sent back to the client
  • ... all of which mean that cookies[:its] = "1999" will not allow you to retrieve that value with cookies[:its].

But wait, it gets more confusing. In a test you do the following:

    def test_cookies
      @request.cookies[:its] = "1999"
       get :index
    end

And in your controller:

    class CookiesController < ApplicationController
      def index
        puts cookies[:its]           #=> nil
        puts cookies.inspect    #=> {:its=>"1999"}
        render :text => ""
      end
    end

The cookies.inspect confusingly returns {:its=>"1999"}, which seems impossible: I put the value in and get nil when I ask for it, but if I inspect the object to see what's up, it's there! Right? Not, not really. The incoming cookies are displayed, not the outgoing. In a typical test-fail-debug scenario, this is a head-scratcher.

For the love of SANITY: do not override methods on core objects to do completely unexpected stuff, and especially don't mangle the expected functionality of operators! I realize that with languages like ruby you can play God, overriding and changing the implementation of anything you please, but some things are sacred: +,-, [], []=, etc. + should add stuff. - should remove stuff. And objects that have [] and []= should let you get stuff with [key] and set them with [key]=value.


1 Comments (from old blog):

At 10/13/2006 5:33 PM, Joshua Jarman said…

I have a slightly different take on the cookies object. It is a hash, with a wormhole inside connecting it to the last and next browser requests. Essentially it doesn't exist in the now. ;-)

Cookies are decoupled. When you set the value it starts a chain of events. The server needs to send the cookie to the browser and the browser has to return the cookie. Then you can read the value.

    cookies[:its] = "1999"

    *server response
    *browser request

      p cookies[:its]
      #=> "1999"

You can use "app" in tests (or the console) to simulate user sessions and to send and receive cookies, which will allow you to get your values back out and check them.

Example:
http://clarkware.com/cgi/blosxom/2006/04/04

So maybe more twisted and misunderstood then broken.

Cheers,
Josh

Trend: Ruby on Rails and Design First Development

Jan 4 ‘07

I went to the SF Ruby Meetup for the first time on June 12; great turnout by all accounts, about 80 people or so. The first presenter, Derek Haynes (Highgroove Studios) talked about building the perfect Rails team, and we've done so at my company if you follow his formula. But more interesting to me is this trend, which other might have known for a long time: design-first development.

Here's what I've gleaned from the few talks I've heard about this: in design-first development, server side modeling is almost completely ignored in favor of really nailing the UI design, flow, features, and user experience. Developers/Designers (devigners?) go strait for the HTML, CSS, and JavaScript, mocking out any AJAX calls to make the design seem like it's really talking to the server. This is iterative, but not in the sense that the entire end-to-end system is designed and refactored along the way. Only after the design is whiz-bang'ed and solid do the developers bolt on (my words) a model layer. I've heard this pushed the Haynes talk, and also by web design guru Dan Cederholm (Bullet Proof Web Design and SimpleBits), and by some members of my own development team.

This is completely foreign to me. I'm model guy, an end-to-end guy. I work from the domain model layer out towards the UI, and get a very simple thing working first, then refactor towards the ultimate design. And even then my UI is going too look like cat puke until I feel like I can devote the time to really getting it right, but usually after the model is solid. So my first reaction it to recoiled from design-first development and start saying works like "scaling!" and "domain-driven development!" and "do the simplest thing possible!" and "YAGNI!" and "models should be understood by our customers!". But is this justified? On most of the Rails projects we're developing for our clients, we knock out the server side stuff, including DB, models, and controllers very quickly (and yes, test the hell out of them), then spend the majority of time in Jails (JavaScript for Rails). And when we have had nice mockups from clients we have stuck to them, for the most part. I'll have to talk to some DFD'ers and see how the bolted-on models hold up.


1 Comments (from old blog:

At 6/16/2006 9:55 AM, DrydenMaker said…

I tend to agree with your thoughts. The difference that is evolving is that the UI is putting on weight and there is more programming going on there that makes the server side easier. We are moving toward the 'programmable web'.

DrydenMaker http://webdevsnob.blogspot.com/

Powered by aintablog