Installing Ruby on Rails on Ubuntu and Windows XP at the same time under Parallels
Installing Rails on Ubuntu and Windows XP at the same time under Parallels

Now that I have my Ubuntu Linux and Windows XP virtual machines running in Parallels (see Street cred? No: Geek cred (Part 1 of 2)), it's time to set them up to run Ruby on Rails. Why? You know... because.

Again, I'm not going to go into excruciating detail, but instead reference the sites that helped me with this and the problems I faced. Luckily there were only a few.

Windows XP + Ruby on Rails == Easy

Here I pretty much followed the instructions on the main Ruby on Rails site. As much as the Rails community loooooooooves their Macs, getting Rails up and running on Windows is much, much easier and faster than any other OS. No ports, no compiling, no apt-get install voodoo. It's just double-click and next-next-next-next-next...

  • download and install using the ruby windows .exe installer. Make sure you select "enable gems" when asked!
  • download and install mysql
  • gem install rails -y
  • gem install mysql -y
  • gem install mongrel_cluster -y

Ubuntu Linux + Rails = Funkadillio

The guide to installing Ruby on Rails on Ubuntu Dapper Drake at Urban Puddle was a very good guide, but I still had troubles. The issues had the same theme: I needed development/compilation tools, which I had not installed as part of the Ubuntu install process. Here are the other things I needed to do:

Ruby Dev Library

I got the following error when trying to gem install mysql -y and gem install mongrel_cluster -y:

extconf.rb:1:in 'require': no such file to load - - mkmf (LoadError)

Solution: install ruby1.8-dev:

sudo apt-get install ruby1.8-dev

make And gcc

The mysql and mongrel gems also complained about make and gcc not being found:

make
sh: make: command not found

and

make: gcc: Command not found

If you get this, install them both:

sudo apt-get install make
sudo apt-get install gcc

Mysql Client Dev Library

I ended up installing this, too, but I'm not sure if it actually fixed anything.

sudo apt-get install libmysqlclient12-dev

That's it so far. I'm planning on setting up the Ubuntu image as a Capistrano deploy target and treating it as a test server.

Check Out the Pivotal Labs Blog

February 6th, 2007

... because it's where I work. We're still working on content.

http://blog.pivotalsf.com

Sitemap Generator for Mephisto

January 14th, 2007

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!

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

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.

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/

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

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/

Just a quick note on the Ruby on Rails irony: there's hardly any ruby to write. This is great for getting things done quickly, but not so great when people really want to learn ruby. A roving consultant friend of ours has dropped by several times to pair program with us, but he's getting a bit frustrated because there is so little ruby to dive into. "It's all JavaScript and CSS and HTML and all that crap!" he says. Right now we're doing mostly UI overhauls, so that's true! It's amazing how little application logic ruby we've written lately compared to the amount of unit and functional test ruby, and compared to the amount of JavaScript, there's no comparison.

Of course, this a good thing -- when the application is solid, you can spend lots of time implementing UIs that designers create.

While chatting about this over lunch someone noted that, since we are in a phase of not doing much RoR and instead writing lots of JavaScript, we're not on Rails... we're in Jails.

Today I paired with a coworker to install SwitchTower to handle our automated application deployment for our Ruby on Rails projects. All in all it seems to work pretty well, though it took all day to install and there appear to either be several confusing bugs. It’s also possible that we missed some documentation, since today is the first day either of us have installed SwitchTower.

Here is a general log of our installation process:

9am – We hit the link above and started reading. The recipe concept looked pretty strait forward so we dove right in. Since our newly minted Subversion server, a Linux box, didn’t have Rails installed, we decided to try using SwitchTower on our Windows development machine. This was our first mistake.

10am – Installation via Gems was a breeze. We followed the instructions and “SwitchTowerized” our project, which created 2 new files in our file system:

  • config/deploy.rb
  • lib/tasks/SwitchTower.rake

We edited deploy.rb, filling in all of our configuration info, and tried to deploy to our offsite demo box.

12pm – After a couple of hours debugging SwitchTower and Rake on Windows we broke for lunch. Rake could not find the tasks specified in config/deploy.rb, and running the default rake deploy did nothing. We fiddled with SwitchTower.rake a bit and attempted to explicitly reference deploy.rb, only get generate some unhappy errors:

rake aborted!
undefined method `set&#8217; for main:Object
./config/deploy.rb:13

“set” is used to set variable for SwitchTower, such as the :deploy_to directory for your application. It seemed bad that this was not working, and after reading some stuff about how SwitchTower only begrudgingly works on Windows, we decided to install Rails on the Linux server that would be running this anyway.

1pm – Luckily my pair knew a lot about compiling and installing apps on Linux using gcc and make, because we had all kinds of problems. From our Fedora Core 3 machine:

  • gcc was not installed: we installed it using yum install gcc
  • Rails install failed with the following
/usr/local/lib/ruby/site\_ruby/1.8/rubygems/custom\_require.rb:18:in require__': 
    No such file to load -- zlib (LoadError)

After some searching we found that we needed zlib-devel, and thus we installed it using yum install zlib-devel

  • We recompiled and installed ruby, rails, gems, and SwitchTower, only to be stopped by openssl
/usr/local/lib/ruby/site\_ruby/1.8/rubygems/custom\_require.rb:18:in require__':
    No such file to load -- openssl (LoadError)

We rolled the dice and did a yum install openssl-devel, since grabbing the –devel version worked for zlib. It worked.

  • And now, with the utmost confidence: Recompile… ruby… rails… gems … SwitchTower… ack! ack! md5… digest… ack! ack! ack! Try to install md5-devel… nothing! ack! ack!…
  • Oh well let’s try again just for fun: … Recompiled… ruby… rails… gems … SwitchTower… bingo! Sometimes you just have to reinstall. Linux zealots are hereby banned from making fun of Windows for this.

3pm – After all of that noise we were finally able to get SwitchTower to talk to our demo box and at least attempt to deploy our app. This is where found that when SwitchTower performs checkouts from version control, it does this from the server running SwitchTower. It seems obvious now, but we were confused at first. Having the SwitchTower server perform all of the source control work is much better than installing Subversion on a bunch of servers.

All was not working but seemed to be well on its way. Here are the final steps:

  • We implemented the restart task as suggested in the documentation to bounce our server
  • Since SwitchTower changed our directory structure a bit, namely adding a current directory in the middle of things, we updated lighttpd.conf as needed.

5:30pm – Everything is working. In addition to normal config changes, we had a few SwitchTower-specific problems, which are either bugs or misunderstandings on our part:

  • SwitchTower did not create the “shared” directory by default as stated in the documentation. More importantly, the shared/log directory was not created automatically, which is problematic since SwitchTower created symbolic links to this directory.

Setting the shared_dir variable explicitly in the deploy.rb file did not fix this. As a result the application would not start until we manually created the ourapp/shared/log directory.

  • According to the documentation, we have many after_ and before_ tasks. Thus we attempted to work around the non-creation of the shared_dir by implementing after_setup in config/deploy.rb.

No dice – it was never executed; maybe we needed to explicitly call it somehow, be we haven’t figured it out yet (please let me know if you know how). We ended up implementing after_update_code instead.

Note that we used the old >/dev/null 2>&1 || true trick to prevent the deployment from failing when the shared_dir already exists.

Not bad for a day’s work. I tried to include many googleable errors and solutions. I hope it helps.

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

I spent much of the week pairing on UI changes on 2 projects, and again the power of CSS is very impressive. It took us about half a day on Monday implementing the UI mockups created by a design firm in CSS, and it make a big difference in the look and feel for the app. I also was exposed to some IE vs. Firefox CSS issues, so that's good stuff to know.

We are now trying to convert Selenium to drive our UI acceptance tests. After investigating Selenium for a few days we realized that we needed a lot more control over the how we wrote our tests, and we also need to take advantage of the drag-and-drop support from the Prototype JavaScript libraries that ship with Ruby on Rails. Selenium definitely does not have the support we need, but it has solved what has turned out to be the Hardest Problem Ever: getting the browser to sit and wait for some content to load. Here's the issue:

  • We load our test in an iframe
  • The setup code in the test loads our target page in another iframe.
  • The test needs to load the target page and wait for it to be fully loaded before simulating clicking on links buttons, etc.

Good luck. Firefox doen't have document.readyState, which is an IE extension. So, we wrote a "wait" loop which just spins for a second or two while the content loads... except that JavaScript loops such as these cause the browser to consume 100% of the CPU, as described in this conversation, preventing the content from loading.

Another option is to use setTimeout('loadMyPage()', 2000). The problem here is that setTimeout() schedules the function to be fired XXX milliseconds in the future, and returns control back to the browser in the mean time. That didn’t do us much good, as we need to sit and wait for the content to load, not to schedule it to load in the future.

After digging into Selenium's code, it looks like they have a clever solution: they use setTimeout() to recursively call the same method again and again, stacking up the calls so that no other browser actions can happen until a state is detected. It's something like this, but don’t quote me since I haven't validated this code yet:

function waitForLoad() {
   if (isThePageLoaded()){
      goOnWithLife();
   } else {
      // THIS IS RECERSIVE!  
      // WE'LL KEEP SCHEDULING
// THE CHECK UNTIL isThePageLoaded()==true
      setTimeout('waitForLoad()', 10);
   }
}

That's the idea -- keep scheduling the check until the state is reached. Right now we're don't have it working completely yet, but the idea makes sense and I think we're close.


6 Comments (From Old Blog):

At 5/02/2006 12:06 PM, DHTML Kitchen said… Hi there fellow selenium user!

Just in reading your post, I'm wondering: can't you just add event listener to the iframe?

iframe.contentWindow.addEventListener("DOMContentLoaded", 
    iframeLoaded, false);

I haven't tested it, but it should work...


At 6/28/2006 8:37 AM, SebiF said…

Does waitForLoad work in IE? It doesn't seem to work for me. Any ideas?


At 6/29/2006 8:01 AM, Joseph Moore said… Hi Sebif --

I'm not sure about IE, but there must be a solution because Selenium uses some veriation of this for it's waitForCondition loop. If you're using this for Selenium, take a look at the Using Selenium's waitForValue, waitForCondition for Ajax Tests thread.

I'll try to whip up an example and try it in both browsesrs.


At 10/09/2006 12:20 AM, Anonymous said…

Hi,

Just happened across your blog via Google.

I'd suggest that if you're waiting for something to occur, that you use a while() loop, rather than a recursive function call.

The reason is that if it's done recursively, every time your interval times out, you get stuff accumulating on your stack which could eventually chew up all your memory.

Instead, use this:

while( !isThePageLoaded() )
  {
    setTimeout('waitForLoad()', 100)
  }

At 11/03/2006 6:02 AM, Anonymous said…

Check out the jQuery javascript library. This has a cross browser 'document ready' function...


At 11/03/2006 8:09 AM, Joseph Moore said…

Thanks for the comments, folks. I'll check out jQuery and will (hopefully) post the latest incarnation of this loop that we use in out apps.

Web Development is... Hard!

January 4th, 2007

It is day 2 at my new gig doing agile/XP and Ruby on Rails; my head hurts. I’m trying to wrap my head around the Ruby language, Rails framework, Ajax paradigms, JavaScript, CSS… namely all the stuff I don’t know well.

I had an interesting conversation with several other developers today. We used to all brag about how we had stayed away from “regular” web development for our entire careers. All of us had developed many apps with a Web front end, but for the most part the heavy HTML, CSS, and JavaScript coding was done by people who specialized in that stuff but didn’t know anything about developing applications. We, oh the special “we”, did the real application development, the server side stuff.

But now that’s changing. Lots of back-end, server-side developers are making the move towards Ajax-based application development because it seems to have real promise. It’s unknown just how far you can push it, but now app-only developers are doing full end-to-end development, and we’re hurting. Guess what? This HTML/CSS/JavaScript stuff is hard! And for those of us that are, well, lacking in the graphical design skills, our pages look bad. Thank god for UI consultant.

Right now I’m paring on some rough drag-and-drop-and-resorting problems. I’m in the “point and question” stage of paring, which is always a balancing act: how much do you slow the Driver down to ask questions versus how much to you hope you’ll just start understanding later? It’ll get better as time goes on of course. I should probably start driving so I can get a feel for the syntax, structure, etc.

Twice, when I’ve started a new job, I’ve been put to work on the hardest problem on the entire application. I didn’t know it at the time, of course, but came to realize this later. I’m hoping that it’s happening again.