Charles Engelke's Blog

May 6, 2009

Rails Metal, Rack and Sinatra

Filed under: Uncategorized — Charles Engelke @ 2:17 pm
Tags: ,

Great talk by Adam Wiggins here at RailsConf.  But this post is more a reminder to me than a synopsis for you.  Find out more at adam.blog.heroku.com and railscasts.com/episodes/150-rails-metal.

Use Named Constants

Filed under: Uncategorized — Charles Engelke @ 12:53 pm
Tags: ,

This morning’s keynote speaker at RailsConf mentioned, in passing, working on some code without named constants.  When something needed to be changed you’d have to find the right instance of it and change it, and hope you changed it everywhere you needed to. It’s elementary that you should use named constants for just that reason.  But this story reminded me of an early programming experience I had with FORTRAN IV on a CDC 6400.

You see, when you write a 1 in your code, you’re kind of using a named constant.  That 1 is is the name of a value (that happens to be one, or 000000000000000000000000000000000000000000000000000000000001 in bits on the 6400).  We always expect that the value of the constant named 1 has to be one.  But in my freshman programming class, I managed to change the value of 1 in my source code to zero.  FORTRAN programmers will probably know how I did that.

This made for a wonderfully oddly behaved program.  The first time through a loop always worked, later ones always failed, and it didn’t matter what values I set before each run.  The story had a happy ending: I learned how to read core dumps and a bit more about machine language, and moved on to other programming languages that make it harder to change the values of literal constants.

May 5, 2009

Testing Your JavaScript

Filed under: Uncategorized — Charles Engelke @ 5:32 pm
Tags: ,

Test your JavaScript in a headless Java browser, as a normal Rake task.  I’m not going to put notes here (I was paying too much attention to write).  Instead, look for the presentation and the necessary plug-in at github.com/relevance/blue-ridge and thinkrelevance.com.  It looks very promising.

RailsConf Keynote

Filed under: Uncategorized — Charles Engelke @ 1:11 pm
Tags: ,

David Heinemeier Hansson is opening the conference, quite appropriately, and saying a lot of interesting things about the past and future of Rails.  The conference is going to post video of the keynote in a day or so, and I recommend watching it.  But what got me sitting up straight and listening more alertly was when he started talking about something else.  Requirements.

David says that programmers treat requirements as commandments from on high.  And that they shouldn’t do that.  The stakeholders aren’t are committed to the requirements as programmers think.  They know what they want, but they’d be just about as happy with a lot of other solutions, too.  And those other solutions might be a whole lot less expensive to provide.

His example concerns chocolate.  He’s got a sweet tooth.  Ask him for requirements to satisfy that sweet tooth, and he’ll specify top quality Belgian chocolates.  Meeting those requirements will take a lot of money and a lot of time.  Maybe that’s necessary.  But try offering a Twix bar right now for just a buck or so instead, and most of the time he’ll actually be happier with that.

The real key to programmer productivity is saying no to requirements as stated, and instead understanding what the stakeholders want to accomplish and opening negotiations with them on the best way to do that.  Requirements are a starting point to that.  They’re not handed down to us on stone tablets.

That means programmers have to be much more involved with stakeholders, and take more responsibility for the ultimate outcome of their efforts.  But they’re going to create a lot more value if they do that.

May 4, 2009

RailsConf 2009 Tutorial – Sinatra

Filed under: Uncategorized — Charles Engelke @ 7:31 pm

My second tutorial of the conference is called “A Hat Full of Tricks with Sinatra”.  Unlike the morning session on jRuby on Rails, I don’t have any specific plans on how I’d use what I learn here.  But the framework looks interesting to me, and I hope to get some good ideas from it even if I never use it for real.

We start by building the minimal “Hello, World” of Rack applications:

run lambda {|env|
[
200,
{‘Content-Length’ => “2”,
‘Content-Type’   => “text/html”},
[“hi”]
]
}

run lambda {|env|
[
200,
{‘Content-Length’ => “2”,
‘Content-Type’   => “text/html”},
[“hi”]
]
}

Put that in a file, like “config.ru” and run it with rackup, for example

rackup config.ru -p 3000

The “.ru” extension is for rackup.  You can call it “.rb”, but then you have to set more things up in the application because it’s actually running regular Ruby code, instead of being read and interpreted in a special context by rackup.

It’s starting out as a very hands-on tutorial, very basic.  But that’s what I want.  If it slowly builds from here, I’ll be happy.

Rack runs an application that is given an environment and emits a response.  The structure allows you to easily write “middleware”.  When Rack’s told to run an application, instead it calls your middleware which can do other things and eventually call your app.  This can be chained.  It’s a simple and powerful tool.

Okay, now getting into Sinatra.  Here’s the core of the application:

require ‘rubygems’
require ‘sinatra’

Huh?  Where’s the code?  That starts up the framework and gets it all working.  If you put those two lines in application and run it (with Ruby) it will start a web server on port 4567.  When you open that in a web browser, you’ll get a blurb for Sinatra and suggestions to proceed.

Want to handle a request to a particular path?  Here’s code that will respond to requests for the root URL and to /greet:

get ‘/’ do
“Welcome to my Sinatra server”
end
get ‘/greet’ do
“Hello!”
end

Nice and clean.  It can also respond to other HTTP verb requests in a similar way.

Now just create a subdirectory of your application directory called “views”, and put a file named “index.erb” in it containing HTML.  Change the code that responds to “/” to:

get “/” do
erb :index
end

Now when you run your application and get the root URL, the HTML in that index.erb file gets returned.  (ERB is “embedded Ruby” even though we didn’t bother to embed any in that HTML.

I’m really liking how this is set up.  Simple always appeals to me, but there’s a lot of power here without messing up that simplicity.

By the way, the sample Sinatra application I’m playing with works just fine under jRuby, too.

I do have one complaint about this tutorial.  It’s not well-structured or planned.  The speaker seems to think he can just open a terminal window and edit and run source code, and we’ll all have no trouble following.  But as soon as one thing is missed, the student has a hard time getting back in sync.  He needs to go slower, he needs to describe what he’s about to do and why, he needs to do it, then he needs to tell what he did and why.

He also needed to plan and rehearse every single example he was going to show.  Instead, he’s winging a lot of it.  The material is trivial to him, but when you’re teaching a class you’ve got to know ahead of time every single tiny glitch you’ll encounter and have to explain.

Another tutorial falls apart in the second half.

Diet Coke Must Die!

Filed under: Uncategorized — Charles Engelke @ 6:33 pm
Tags: ,

I’m here at RailsConf looking for a bit of cold, free, sweet caffeine at the break.  There are plenty of sodas, and they’re even the right brand – Coca-Cola.

But unless I want a lot of empty calories, my only choice is Diet Coke.  Which is drinkable, but only barely.  (Pepsi fans: don’t gloat.  No other brand of diet cola reaches even that level.)

This is a travesty because now Coke Zero exists.  Somehow they’ve managed to create a diet cola that really tastes like Coke (the only cola that has ever mattered)!  But you can almost never get it at a meeting or restaurant because they’ve got the old standby Diet Coke.  And Coca-Cola is fine with that because it helps in their goal to fill supermarket shelf space with several thousand different products all called Coke.

Coke Zero is a better choice than Diet Coke in every single circumstance.  Coca-Cola, you’ve got a responsibility to us – fix your advertising and branding and GET RID OF DIET COKE!  Let Coke Zero take off and fly!

And while you’re at it, get rid of Cherry Coke, Caffeine Free Coke with Lime and Splenda but without added Vitamins, and all those other stupid variations.  There are only two drinks worthy of the name “Coke” – Coca-Cola and Coke Zero.

RailsConf 2009 Tutorial – jRuby on Rails

Filed under: Uncategorized — Charles Engelke @ 12:06 pm
Tags: , ,

I’m starting this year’s RailsConf with a tutorial on jRuby on Rails.  I’ve fiddled with it a few times, and I have the distinct impression that it’s a more stable production platform than the regular Ruby interpreter.  But there are a few issues I’ve had.  I hope today’s tutorial will help me resolve them.

I’m not much of a note taker, so this (and other posts this week) will probably be pretty thin, with just reminders of core information tidbits I glean here.

The speaker is Nick Sieger of Sun Microsystems, and he’s put his slide desk online at his blog.  The link to the actual slides isn’t there (yet), so I won’t put it here, either.  It looks like he’ll probably soon put up a post with the link.

The talk is going to start from absolute zero.  Since I’ve actually installed and used jRuby (very casually) there will be some familiar stuff for me at first.

Download GlassFish, a Java application server we’ll be using.

Download jRuby, too (this is the latest production version as of today).

You’ll need the real JDK, too.

Install the JDK.  Add its bin subdirectory to your path, and set an environment variable named JAVA_HOME to the root of the JDK install.  Test it by running “java -version”.

Install jRuby by unpacking it anywhere you want.  Add its bin subdirectory to your path (he emphasizes adding it to the end of the path).  Test it by running “jruby -v”.  Run irb or other Ruby tools by prefixing them with “jruby -S”, as in “jruby -S irb”.

Run jRuby with the Java “server” VM with “jruby –server”.  That’s better overall performance, at the cost of slower startup.  You can pass a variety of Java arguments to the JVM with “jruby -J<argument>”.

Oh, you want jRuby at the end of the path so that its utilities don’t run when you want the regular Ruby ones.  So “rake” gives the regular Ruby rake, “jruby -S rake” gives the jRuby one.

jRuby has all the standard 1.8.6 Ruby things – the libraries, RubyGems, Rake, RSpec.  It’s also integrated with the Java libraries.  Go into jRuby’s irb, and type

java.lang.System.out.println “Verbose Hello”

It works!  Not that you’d want to do that, but I’m sure I’m going to want to use the Java cryptographic tools.

Install a bunch of needed gems (I had to be in a command shell with administrative privilege to do this in Windows 7):

jruby -S gem install rails mongrel jruby-openssl

Now, just create a Rails application with “jruby -S rails appname”.

Install ActiveRecord-JDBC or MySql or SQLite3 (or both):

jruby -S gem install activerecord-jdbcmysql-adapter
jruby -S gem install activerecord-jdbcsqlite3-adapter

Now fix your Rails application’s database.yml to point to the JDBC version of the appropriate database adapter.  For example, “adapter: jdbcsqlite3”.

Now here’s a trick I could have used (and will be using)!  Use embedded Ruby to have a single configuration file work for both jRuby and MRI.  Put this in database.yml:

<% jdbc = defined?(JRUBY_VERSION) ? ‘jdbc’ : ” %>
development:
adapter: <%= jdbc %>mysql

[I just noticed that WordPress is “fixing” my single and double quote marks, even in code.  It’s easier for me to tell you figure out that they’re really all straight quotes than to figure out how to get them in WordPress right now.]

And now create a Rails application in the regular ways.  Just remember to use “jruby” instead of “ruby”, and to prefix other commands (like rake) with “jruby -S”.

Found a bug (in jRuby? in Rails? hard to say, but probably either in Rake, or in a Rails Rake task): if your Rails application’s environment.rb specifies needed gems, you can usually install them with:

rake gems:install

But, if you use:

jruby -S rake gems:install

it says it works, but it doesn’t (“jruby -S gem list” doesn’t show them).  It appears that it installs these gems under MRI instead of under jRuby.  Of course, you can just manually install each needed gem with “jruby gem install”.  It’s just the Rake task that gets derailed.  Note that this happened under Rails 2.2.2, which is what our existing application under development is currently using.  I haven’t checked to see if it still happens in Rails 2.2.3 (the current version as of today).

You can speed up Mongrel under jRuby by removing the mutex it no longer needs.  You have to edit Mongrel’s source to do this.  Look for the block starting “@guard.synchronize” and comment it out.  You have to also set “config.threadsafe!” in your application’s appropriate environment file to have this help (or change it globally for Rails under jRuby by editing lib/initializer.rb there.

The speaker’s JRuby-Rack gem allows you to run any Rack-based application (like Rails) under any Java Servlet API server.  That sounds promising for production use.  I’ve got to learn a lot more about the Java server ecosystem to take advantage of it.

The talk is now really turning to ways an experienced Java shop can run Ruby on Rails well in their infrastructure.  There’s a lot of background I don’t have, so this can point me to the right place to start, but I can’t understand it well enough to use it as a result of this talk.

Lots of talk on Warbler – I don’t have the context to understand it now (or know why I should care).

Google App Engine with jRuby.  Now, this interests me.  There’s going to be hackfest on Wednesday night at CabooseConf (a side meeting to RailsConf) that I’m going to want to visit.  Of course, Java support on Google App Engine is very preliminary, and there are lots of restrictions.  But the speaker says that jRuby on Rails works!  Well, except for a few minor issues like no ActiveRecord.  Not real practical yet.  But very encouraging.  There’s a talk at 11:45 AM this Wednesday that goes into more details.

[Side note: I’ve been trying to get our current development application running here in different configurations, and found I couldn’t get it to run under MRI using MySql (jRuby with MySql, or either with SQLite3 worked fine).  This isn’t related to the talk, but I found the solution on Google.  If you’re running a 64 bit version of Windows, you either need to be running MySql 5.0.x instead of 5.1.x, or else get the libmysql.dll file from an older version of MySql and put it in your Ruby’s bin subdirectory.  I don’t want to forget that the next time I wipe and reinstall everything on my laptop, hence this note.  It would be really nice if the precompiled gem for MySql gets fixed to avoid this problem, but I’ve noticed that the Windows platform is often not given much attention in the Ruby and Rails communities, so I’m not holding my breath.]

The tutorial has hit a real lull for me.  The Java ecosystem is incredibly rich, and layered upon layers.  It’s very hard for an outsider like me to keep track of the 27 billion different kinds of tools out there, and we’ve been talking for about an hour about those.  From the perspective of a Ruby person wanting to leverage some of that Java stuff, well… yawn.

We’re wrapping up now.  There was a lot of value to me in the first half of the talk, but not in the second half.  And I don’t think it’s just me.  It seems like the speaker got really bogged down at this point.  Overall, worthwhile, but it could have been even better.

May 2, 2009

Kindle Demographics

Filed under: Gadgets,Notes — Charles Engelke @ 4:26 pm
Tags:

Engadget pointed me to a post on the Kindle Culture blog that claims that most Kindle owners are over 40.  The research behind the claim is a bit informal, but it seems credible.

So (assuming this is true) why are Kindle owners older than other gadget owners?  The Kindle’s expensive, but I don’t think that’s it.  A lot of extremely expensive gadgets are very popular with teenagers and twenty-somethings.  The ability to change the font size may be a small factor, but I don’t think that’s behind this either.

I think it’s because lifelong readers tend to keep a lot of their books, and eventually there are so many they’ve become overwhelming.  I’m 53, and based on rough estimates from linear shelf space and overload factors, my wife and I have somewhere between 5000 and 10,000 books in our house.  It just seems natural to hold on to them, but we’ll only reread a tiny fraction of them.

The Kindle (well, Kindles, one for each of us) lets us keep reading new books without adding to the shelves, piles, and mounds of books we’ve got.  I was very slow to get one because of the DRM – I don’t really own any of the books I’m buying, and I don’t expect to be able to still read them a few years down the road.  But if I want to reread a book in a decade or two or three, I’ll just buy another copy then.  Thanks to electronic publishing, anything I want is likely to still be “in print”, and it’s less expensive to buy a few duplicate copies than to get a bigger house to save all that paper.  And the Kindle is just about as good a physical reading experience as a typical paper book.

I will still buy some paper books.  The Kindle’s screen isn’t big enough for most technical books (in my opinion).  And there are books I’ll want to have and keep for sentimental reasons.  But I’d be pretty happy if I could get the paper book count in the house down below 1000 some day.

March 4, 2009

Update: Web Hosting with Google AppEngine

Filed under: Uncategorized — Charles Engelke @ 9:55 pm
Tags: ,

I’ve been getting some comments recently on last summer’s post on Google AppEngine for web hosting.  I guess I’m not the only one who wants to add some simple static web pages to my Google Apps hosted services.

Most commenters are reporting success with the method, but Peter G has a problem getting the pages to work right at the naked domain name.  That is, pages at http://www.example.com work fine, but the same pages at example.com don’t.  Why did it work for me, but not him?  I had no idea.

I had to set up a new domain for a friend anyway, so I paid close attention to how to set this up.  And found that I couldn’t make the naked domain name work, either.  A little clicking around found the problem:

I’d like to map my app to http://myurl.com (also known as a naked domain).

Due to recent changes, Google App Engine no longer supports mapping your app to a naked domain.

Well, that’s just great.  I don’t know what recent changes caused this, but you apparently can no longer make AppEngine serve pages for a naked domain name.

The documentation does describe one solution: URL forwarding.  For this to work you need your domain name service provider (which is probably your domain registrar) to return an HTTP redirect response to any requests at the naked domain.  Then any web request to example.com/some/page gets redirected to http://www.example.com/some/page, which AppEngine will serve up fine.

The new domain I was setting up was registered with eNom, so I used their DNS dashboard to add a record saying that requests to @ (the symbol for a naked domain) should generate a URL redirect to http://www.example.com, and it all just works.

Hope this is helps anyone having trouble with this.  There is one potential problem, though.  The solution depends on services from your domain registrar, not Google Apps, so you may be out of luck if your registrar doesn’t offer URL redirection.

March 1, 2009

Macon in the Snow

Filed under: Uncategorized — Charles Engelke @ 6:30 pm
Tags: ,

Macon, Georgia is in the middle of the state, well south of Atlanta, and it does not get much cold weather.  It certainly doesn’t get much snow.  But it did today:

Our Snow-Covered House

Our Snow-Covered House

Not everyone was pleased with it, though:

Our Snow-Covered Dog

Our Snow-Covered Dog

February 25, 2009

CodeWright Font Update

Filed under: How To — Charles Engelke @ 3:18 pm
Tags:

Many years ago I posted a note on a Windows XP registry fix for CodeWright’s ugly fonts.  Brijesh sent me a comment that he just tried it and it didn’t work for him.

Well, I haven’t used CodeWright in several years because it’s essentially an orphaned product.  I guess some Windows XP update changed things so the registry hack doesn’t work.  But some of my co-workers are using CodeWright 6.0, and they’ve fixed the ugly fonts from within CodeWright itself.

Select Tools/Customize/View Setup, then click on the Font tab.  Instead of the default font it already chose, select a font you want.  They’re using Consolas (available for download from Microsoft, but I won’t link to it because Microsoft constantly moves things).  Go to their download center and search for it.

Consolas is fantastic for programming because the comma and period (and hence the semi-colon and colon) are very visibly different.

Hope this helps.

January 30, 2009

My first real Windows 7 glitch

Filed under: Notes — Charles Engelke @ 9:55 pm
Tags: ,

Today I tried to print a file in the office, and couldn’t.  I was able to search and find the print server and the right printer, but I couldn’t get it to connect.  Windows 7 just said “Connecting to…” for several minutes.  Trying another printer eventually got past that screen, but then Windows 7 immediately demanded that I provide an .INF file.  Which I didn’t have, of course.

I’d already printed to a network printer at home, so why didn’t it work at the office?  I don’t know, but I’ll spend some time fiddling with it next week.  I can’t see any reason for Windows 7 to have trouble with this.

On the good news front I now have a working VPN client.  NCP sent me a download link for the their beta Windows 7 VPN client, which is good for 30 days before I’ll have to purchase it.  I had a little trouble configuring it because there are a nearly infinite number of configuration options and it wasn’t clear to me which ones I should choose.  But then I remembered reading that it could import a saved Cisco VPN configuration file.  I imported the one I’d used in Windows XP, and it immediately connected and worked perfectly.  So I guess I’ll be buying a copy soon.

I’m annoyed with Cisco, though.  They sold us VPN concentrators and I feel they’re responsible for providing client software to connect to them.  It’s irresponsible for them to not support 64-bit versions of Windows.

January 29, 2009

A few more days with Windows 7

Filed under: Notes — Charles Engelke @ 10:37 pm
Tags:

I’m still using the 64-bit beta of Windows 7 as my primary operating system and it continues to impress me.  The only glitch I’d had before was the video driver crashing occasionally (and restarting seamlessly every time).  But even that’s stopped happening.  I don’t know why (there’s been no driver update related to it) but I’m sure not going to complain.

More software installed and working well for me:

When I tried to install Skype, Windows 7 popped up an alert that there were known compatibility issues with it, and gave me a link to another page at Skype with a specific beta version for Windows 7.  Handy.

And I’ve been in the office with my ThinkPad undocked, docked with an external monitor, and sometimes connected to a projector.  Windows 7 does a fantastic job of detecting all the changes to my video connections and adjusting the display configuration and resolution perfectly every time.  It remembers that I extend my display to the external monitor when docked, but duplicate it to the projector when that’s connected.  It just works.

I’m still waiting for something awful to happen, but things are sure going great so far.  There’s been tremendous attention to detail on Microsoft’s part.  That, more than slick new technology, is making Windows 7 a pleasure to use.

January 25, 2009

Trying out Windows 7

Filed under: Notes,Uncategorized — Charles Engelke @ 3:32 pm
Tags:

Last Tuesday I finally took the time to swap out hard drives on my laptop and install the new Windows 7 beta.  I was skeptical thanks to my Vista experiences (which I shared on this blog), but there was a lot of good buzz on this one.  I decided to go whole hog and install the 64 bit version to make it more challenging.

The buzz is right.  Windows 7 is much better than Vista was.  In fact, I’m having fewer problems with it in beta than I did with Vista after it had been out for a year.  It seems to be pretty much the same as Vista and the core, but Microsoft has paid a lot more attention to details this time, and it makes for a much better experience.

Windows 7 boots fast, and performs fast.  I don’t know if it would benchmark better than XP, but it in day to day use it’s been quicker for me than XP is.  The user interface changes are actual improvements, and enhance working with the PC.

The installation took well under half and hour, and went flawlessly.  Upon first boot, everything was working fine, but there were a couple of rough spots:

  • The eye candy (translucent title bars, et cetera) didn’t work
  • I couldn’t turn off the trackpad part of my ThinkPad TrackPoint
  • About four devices, including the fingerprint reader) showed problems in the device manager

Running Windows update solved most of the problems.  I downloaded a couple of drivers from Lenovo for the TrackPoint and fingerprint reader.  That fixed the TrackPoint, but not the fingerprint reader.  Then, about a day later, Windows popped up an alert telling me there was a problem with the fingerprint reader, and would I like to fix it?  I said yes, and it directed me to a site to download the right driver for it, and after that it worked fine.

So right now, everything is working, and working well.  The only operating system issue I’ve had has been the NVIDIA display driver locking up for a few seconds a couple of times.  Windows reports that it crashed and restarted, and after each restart, everything was fine.  I could actually live with that happening a few times a week if needed, but I’m sure NVIDIA will get it fixed long before general release of Windows 7.

Almost all the software I use installed and works fine, too.  No problems with:

Picasa 3 works fine, except that the screen saver doesn’t seem to actually trigger.  It says that it is set up to run, but Windows 7 doesn’t seem to know it exists.  Oracle web conferencing wouldn’t install automatically, but it did when I downloaded and ran the setup problem.  It seems to run okay now, though.

Windows actually suggested AVG as an antivirus solution, as well as Norton and Kaspersky.  Since I’ve been using AVG for a while, I first installed and used Kaspersky to make the test more challenging.  It worked, but it was often popping up alerts that an update was needed, and then when I manually ran an update, saying that it wasn’t needed.  It was too chatty and tried to do too many things (like being a network firewall, too), so I dumped it and went to AVG, which has been working well.  I guess.  I supposed I’d have to try to infect the PC with a virus to know for sure!

What didn’t work?  Just two programs: Google Chrome and Cisco VPN Client.  I really like Google Chrome, but the installer isn’t happy when it’s run.  I finally got it installed, but it won’t display any web pages.  There are suggestions online about ways to get it to run, but they involve telling it to operate in a less secure mode, so I’ll wait for an update from Google fixing the problem.

The lack of a VPN client is a much bigger problem for me.  I can’t really stay in Windows 7 without it (though I’ll use it for at least another week and live with the hassles that long).  Cisco apparently has no intent to ever support 64 bit windows clients.  Personally, I think Cisco does a lousy job supporting client systems, period, and would like to not use them.  NCP does have a compatible VPN client that runs under 64 bit Vista, but they warn it won’t work under Windows 7.  They have a Windows 7 version in beta, and I’ve requested a copy to test.  They’ve agreed, but I don’t have it yet.  I’m hopeful about it.

The way things have gone during my five day test (so far), I could see myself having this beta as my regular operating system while I wait for the real release.  If I can get a VPN client, and don’t run into major problems, I’ll probably do that.  Though I’m keeping my XP hard drive with me at all times, ready to swap back to it if I need to.

November 6, 2008

RubyConf ’08

Filed under: Uncategorized — Charles Engelke @ 10:45 am
Tags: , ,

I’m at RubyConf in Orlando through the weekend.  Today starts with a keynote by Matz, followed by three parallel tracks.  I’m going to try to switch from track to track between talks, not just a breaks, but I don’t know whether the timing will work.

Matz’s keynote is “Reasons Behind Ruby.”  His reason for Ruby is that it’s his masterpiece, and it lets him maximize freedom.  But what about for the rest of us?  Ruby’s imperfect: it’s slow, it’s complex, it’s inconsistent, it’s poorly implemented (in MRI), and so on.  So why do so many people love Ruby?

Ruby’s enjoyable, it makes programming fun again.  Again?  When did it stop being fun?

Geez – Matz learned programming with BASIC on some kind of programmable calculator.  (Actually, BASIC was my first programming, language, too.  But on an IBM 360.  Which was probably about as powerful as his calculator.  So how come I haven’t created a great programming language?)

Matz loved the control from programming, but BASIC was limiting.  His next language was LISP.  A little different.  He liked it, but didn’t really love it.  (And a lot of LISP people feel that everybody should love it.)  He wanted to be in charge of his programming language.

His analogy: BASIC at one side, LISP at the other… over the edge of a cliff.  He shows a big space between BASIC and the edge of the cliff, which is where he wants to be.

Ruby on Rails turns Ruby into a web DSL.  Ruby lets you create your own specialized languages, but stay within Ruby.  Rake is a DSL for building an application, RSpec is a DSL for testing.  LISP is good for building DSLs, but so is Ruby.

There are fewer than a million Ruby programmers now, but Gartner predicts more than four million by 2013.  That isn’t necessarily good, unless the Ruby community stays as open and positive as it has been.

Matz closes with thanks to all of us!

September 3, 2008

Google Chrome

Filed under: Notes — Charles Engelke @ 10:24 am
Tags: ,

I’m excited about Google Chrome.  It’s in Google’s best interests to make the Internet ever more usable, and when they do it through pure open source it helps everybody with similar interests (even Google’s competitors).  But I’m also pleased because it has three specific features that I’ve wanted a lot lately as I’ve been living more of my computing life online:

  • Minimal “chrome”.  That is, almost all of the web browser is given over to what’s inside the page I’m using, not to browser functions.  I’ve stripped Firefox’s chrome down as much as I could, but Google Chrome is even better than that.
  • Tear-away tabs.  I can grab a tab and drag it outside of my browser, and have it stand on its own.  I love tabbed browsing in general, but sometimes it gets in the way.  Just as I often want to have several command shells open and visible at the same time, sometimes I want browser pages set up the same way.
  • Application windows.  You can turn a tab into an “application” that can be started from a menu or shortcut like any other application, and which has even less browser elements around the page.  I’ve already done this for my Google Mail, Calendar, and Docs pages, and my blog administration page.
Professionally, I’m interested in building web applications, and Google Chrome is a great frame for them.  It doesn’t have a lot of features yet, but it’s definitely ready for solid use.

August 17, 2008

iPhone’s Great – and Grating – UI

Filed under: Gadgets — Charles Engelke @ 12:46 pm
Tags:

I’ve been using my iPhone 3G for a bit over a week now, and I’m impressed with it.  But it can be pretty annoying, too.

The lousy cellular radios have been widely documented, and that’s certainly annoying.  But it’s the user interface that’s grating.  Don’t get me wrong: it’s amazing and very easy to pick up.  But it’s not always easy to use.

The biggest problem comes when trying to use it in the car.  Yes, I use a hands-free headset, but the “soft buttons” (instead of real ones) make dialing dangerous.  You have to look at the phone while dialing, and the form factor even makes doing that one-handed nearly impossible.  It’s not just dialing, even answering or hanging up is very difficult.  In fact, hanging up is particularly hard because there are about eight different soft buttons on the screen, and you’ve got to hit the right one or something undesired will happen.

At the very least, the iPhone needs voice dialing.  There’s a free add-on app for that, but getting it launched is harder than manually dialing, and then it doesn’t seem to work very well.  Good voice dialing and headset integration are vital.

The other UI issues are just annoyances.  The iPhone is optimized for brand new users, and it is very easy to just start using it.  But lots of operations should have alternate navigation options.  For example, if you’ve got multiple e-mail accounts on the iPhone it takes six clicks to go from reading a message in one inbox to another.

If the iPhone were truly an open platform I’m confident that fixes for these problems would come from somebody, even if not Apple.  But, though it’s more open than it used to be, the iPhone is still a closed platform.  I’ve got high hopes for the Android platform.  Maybe I’ll get an Android phone once Sprint or Verizon has one.

August 10, 2008

iPhone 3G First Impressions

Filed under: Gadgets — Charles Engelke @ 7:56 pm
Tags:

It’s seemed to me that developing specialized business applications for hand-held platforms was a losing game.  The hardware’s got plenty of power, but not enough physical size for a decent UI for a complex application.  The platforms are always changing, and your code has to keep changing as a result.  And there’s never been a single platform universal enough to cover our prospective user base, so we’d have to support a lot of incompatible devices.  We’re doing that now, but only for very limited kinds of functionality.

When handhelds got merged with phones and started sporting web browsers it looked like it might be the solution to this problem.  We could provide web applications and regardless of platform all users could connect to them.  But the web browsers all stank, and you still had too little screen space to put your UI in.  I used a Blackberry for a few months to evaluate it for this purpose, and I couldn’t stand it.

Then Apple brought out the iPhone with what looked like a seriously good web browser.  But it was marketed as a consumer entertainment device, not something a business could use.  So even if we built web apps that gave a great experience on it, our customers wouldn’t be buying iPhones to run them.

And then the second generation iPhone was announced with features aimed at businesses.  And Google’s been working on the Android platform that will have a very similar web browser.  So I decided to get an iPhone and try it out.  It took four weeks to get one, but it finally arrived Thursday and I’ve been using it since.  Some early impressions, in no particular order.  Well, that’s not entirely true; I’ll start with the bad:

  • Apple’s marketing to businesses, but not making it very easy for us to get iPhones.  We can’t buy them at an Apple store for our business account, and we’re not going to have employees wait in line for hours to get them in any case.  And Apple seems to have shipped a lot more units to their own stores than to AT&T, which kept telling us they’d have a phone for us in a few more days.  We need to be able to just place an order and get it filled in a timely way.  I hope to see this get better, but I’m not sure it will.
  • I don’t like being stuck with a single carrier, but if I have to be I sure wish it wasn’t AT&T.  Their high-speed coverage area is pathetic compared to Verizon or Sprint.  We only have EDGE here in Macon, though our Gainesville office has 3G.  And our customers don’t spend most of their time working in big cities, so they’ll also have only EDGE until AT&T gets its act together and makes 3G universal on their network.
  • The cellular radio in the iPhone isn’t very good.  In my house I get cellular service on it only about 10% of the time.  My wife’s old Motorola (also on AT&T) always gets service, usually two bars strength though sometimes dropping to one bar.  Since I’m starting to tell people to call my GrandCentral number to reach me, not having cellular service in my house isn’t a big problem, and I can always hope it will improve.
  • Another damn cable to carry.  The iPhone sync and charge cable is USB at one end, so why didn’t Apple make it USB at the other end, too?  I have lots of USB devices so I’d always have the necessary cable.  (I suppose I know why Apple did this; the cable is the same one as used for the iPod.  I don’t care.  I’m sick of incompatible connectors.)

Now the good:

  • The overall user interface is seriously good.  Really impressive.  There are a few rough edges where simplicity is favored over efficient use (such as navigating between e-mail accounts).  That’s good for users starting out, but I’m already wishing for more ways to navigate in a hurry.
  • The web browser is powerful, relatively standard, and has been fit into the small display area very, very well.  I particularly like how double-tapping a logical part of a web page magnifies and centers just that part.  Our existing web applications work just fine on it, and a little bit of design work could make them absolutely fantastic on this platform.
  • Cisco VPN connectivity works perfectly.
  • There’s some nice integration between the different applications, usually via the web browser (even if the starting application is a native one).
  • Some of the applications available are amazing.  The Maps one is great.  Midomi lets you hum a tune (very badly in my case) and then actually figures out what the song is.
  • Every Internet-connected application I’ve tried, other than heavy duty web surfing, works just fine at EDGE speeds.  Even streaming music works.  I don’t think streaming video would, but there’s very little capability for that on the iPhone anyway.

And there are things that aren’t bad, but I want to be better.  I expect them to get better, too:

  • It’s an ever more open world.  It’s nice that Apple supports Microsoft Exchange, but it’s not enough.  I can sync my Contacts with Google, but not my Calendar.  (The Google Mobile applet for the calendar is so good I hardly need it, but I’d still prefer to have the native Calendar sync.)  I can’t sync my Notes anywhere at all.
  • I can read PDF files, but not easily and not well.  Trying to read a 10MB PDF book freezes the iPhone completely.  Putting it on Google Docs gives me a 404 Not Found when I try to read it.  Opening it from a Google e-mail attachment via the web browser (not e-mail application) finally worked.
  • I dislike web pages that use Flash for normal functionality, but there are some things Flash works very well for.  The iPhone doesn’t have it.  It needs it.  It’s probably the minimum requirement for any kind of web conferencing.
  • I’ve used AT&T international roaming before, and it’s not bad.  The price is outrageous, but it’s a lot more convenient than getting pre-paid local SIM cards everywhere I go (and the iPhone is locked, so I couldn’t do that with it anyway).  But international data roaming prices are completely unacceptable.  AT&T offers an unlimited International data plan for their Blackberries; they need to offer it for the iPhone, too.

It looks good for the iPhone to replace my Palm PDA and Motorola cell-phone as well as providing a ton of new capabilities I’ve never had before short of a laptop.  I’ll live with it on the road for a while and see.

July 31, 2008

AppEngine “Rewrite Rules”

Filed under: How To — Charles Engelke @ 8:43 pm
Tags: ,

Yesterday I showed how to get a basic static web site hosted on Google AppEngine.  But I need a little bit more than a purely static site.  My blog used to be hosted at engelke.com/blog and http://www.engelke.com/blog, but now it’s at blog.engelke.com.  So any existing links to my blog entries will break.  That is, they’ll break unless requests to engelke.com/blog/something get redirected to blog.engelke.com/something.

I did this with a rewrite rule when my site was being served with the Apache httpd server.  The specific rule I had was:

RewriteRule ^/blog(.*)$  http://blog.engelke.com$1  [R]

That says that a request that starts with /blog will be redirected to one at blog.engelke.com followed by whatever followed the word blog.  Which is actually kind of wrong; for example, this will redirect a request made to engelke.com/blogging to blog.engelke.comging, which is nonsense.  I really should have given two rules:

RewriteRule ^/blog/(.*)$  https://blog.engelke.com/$1 [R]
RewriteRule ^/blog$  https://blog.engelke.com/        [R]

The first rule says that anything starting with /blog/ will be redirected to blog.engelke.com/ followed by whatever was after blog/.  That handles everything but a request to engelke.com/blog just by itself.  The second rule handles that.

AppEngine’s url: mapping rules in app.yaml kind of look like rewrite rules.  For example, the mapping:

- url: (.*)/
  static_files: static\1/index.html

That says any request that ends with a slash should be served with the file at that relative directory followed by index.html.  But that’s not a redirect.  The browser still requests the URL ending with the slash; the server just returns the contents of a particular file.

No, if we want redirection similar to the rewrite rules I had, we’ll need to write an AppEngine script.  First we add two url: mappings to app.yaml.  These should be placed before the existing ones:

- url: /blog/.*
  script: redirector.py

- url: /blog
  script: redirector.py

These correspond to the first part of the old rewrite rules, but they don’t tell what the response should be.  Instead, they just tell AppEngine to run the redirector.py script and let it figure out what to do.

I started writing the redirector.py script with a standard skeleton from the AppEngine documentation:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

application = webapp.WSGIApplication(
            [
            # pattern to handler mapping pairs go here
            ])

def main():
   run_wsgi_app(application)

if __name__ == "__main__":
    main()

The “pattern to hander mapping pairs” are each a string that’s a regular expression to match and the name of a class to handle those request paths.  The following two lines match both patterns and invoke the BlogHandler class for them (the ‘r’ in front a string just tells Python it’s a “raw” string, so Python doesn’t interpret any characters in any special way):

     (r'^/blog/(.*)', BlogHandler),
     (r'^/blog$',     BlogHandler)

The BlogHandler class contains methods for each HTTP method to be handled.  We’ll just handle GET and HEAD requests, since those are the only kind our blog will respond to anyway.  The pattern matched inside the parentheses will be passed as a parameter to each of these methods (and self is always going to be passed as the first parameter in Python).  The second pattern doesn’t have any parentheses, so that matching string parameter will be missing; our handlers will have to accept that.

Here’s the code for the BlogHandler class:

class BlogHandler(webapp.RequestHandler):
    def get(self, tail = ''):
        self.redirect('https://blog.engelke.com/'+tail, permanent = True)
    def head(self, tail = ''):
        self.redirect('https://blog.engelke.com/'+tail, permanent = True)

This code is pretty simple and should be self-explanatory.  If no second parameter is given, the methods act as if an empty string was passed.  The optional “permanent = True” parameter makes the redirect an HTTP status 301 Moved Permanently so that client programs can know to never bother to look at the old address.

Complete code

The new app.yaml file is:

application: engelkeweb
version: 1
runtime: python
api_version: 1

handlers:
- url: /blog/.*
  script: redirector.py

- url: /blog
  script: redirector.py

- url: (.*)/
  static_files: static\1/index.html
  upload: static/index.html

- url: /
  static_dir: static

The redirector.py script is:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class BlogHandler(webapp.RequestHandler):
    def get(self, tail = ''):
        self.redirect('https://blog.engelke.com/'+tail, permanent = True)
    def head(self, tail = ''):
        self.redirect('https://blog.engelke.com/'+tail, permanent = True)

application = webapp.WSGIApplication(
            [
                (r'^/blog/(.*)', BlogHandler),
                (r'^/blog$',     BlogHandler)
            ])

def main():
   run_wsgi_app(application)

if __name__ == "__main__":
    main()

And that’s my AppEngine hosted web site.  The one problem left is that requests that should have a trailing slash, but don’t, won’t work (other than /blog, handled above).  But there are only two such possible pages on my site, and I’ve never posted links without the trailing slashes.  So I don’t need to deal with them.

Though I did.  I just added mappings for those two raw names (/xhtmlref and /charles/TPC5) to the redirector.py script, and added a class to redirect those requests to the right URL with the trailing slash.  But that doesn’t show any new ideas, so I’m not going to put the additional code here.

Handy GrandCentral Hack – and a Few Complaints

Filed under: Google IO 2008 — Charles Engelke @ 5:48 pm
Tags: ,

[Update on August 1: Chad, the author of the Firefox extension I refer to below, commented and asked for details of the problem I had.  His comment and my answer are available for this post.  In a nutshell, I reinstalled the extension and this time it’s working for me and not causing any problems.  Great responsiveness from a software author, and a great tool for GrandCentral users  Thanks Chad!]

GrandCentral is a service that gives you a virtual phone number that can be pointed at one or more real phone numbers.  If someone phones the GrandCentral number, all the real phones get the call.  There are a lot of extra features, too, like e-mail notification of calls, web voice-mail, switching which phone number you’re using while a call is underway, and more.  But you probably can’t get it because it’s in an invitation-only beta period.

Unfortunately, GrandCentral has been “in beta” for quite a while now.  I got my account in May 2007.  I never seriously used it because I wasn’t sure it would last, and I also wasn’t sure I wanted to be quite that easily reached.  But I saw a tip on Lifehacker the other day about it and gave it a try.  It turns out that you can call anybody from your phone for free using GrandCentral.  Just put the person’s phone number in your address book and you’ll see a Call button.  Click it, and GrandCentral first calls you.  When you answer, it announces that’s it’s placing your call, and it calls the number you selected.  It works perfectly.  I don’t know whether this works for calls outside the US, but I doubt it.

This is handy for me to call the office when I’m working from home.  I prefer to use my home phone instead of my cell phone due to coverage issues.  But our office is a long-distance call, so I use the 800 number.  Which connects me to the receptionist who I have to keep bothering in order to connect to the right extension.  Now with GrandCentral I call the other employee’s direct-dial number from my home phone for free, and don’t have to take up the receptionist’s time.

This trick does require that the person be in your GrandCentral address book, which is a bit of a pain.  The Lifehacker tip was about a Firefox extension that would let you make this kind of call to any number on any web page, but the extension didn’t work for me and caused some other problems in Firefox, so I removed it.  If I could upload a file of phone numbers to the address book this wouldn’t be much of a hassle, but I can’t.  GrandCentral makes you enter each contact individually on the web.

Which brings me to my complaints.  GrandCentral now belongs to Google, and they don’t seem to be doing anything with it.  It’s not integrated with any other Google services (like my GMail contact list).  It’s got an awful flash-heavy user interface that makes every navigation step slow and difficult.  And it doesn’t have any of Google’s normal thoughtful touches (like being able to upload an address book).

I can’t see how anybody can make money with the GrandCentral service, at least as it now exists, which may be the problem.  Perhaps it’s almost an orphan product inside Google.  It wasn’t even mentioned at the Google IO meeting.  Too bad, because it can be really useful.  I guess I’ll use it while I wait to see what Google does with it.

« Previous PageNext Page »

Blog at WordPress.com.