Nasty bug with binary files, Rails and erb.rb – how to fix it

OK, so I happily hack away on my  Rails application on a Debian box with Ruby 1.8.7 and Rails 2.1.0, and then deploy to a Fedora 8 server with Ruby 1.8.6 and Rails 2.2.2. All of a sudden a particular release causes Passenger to spit an error page on application startup. The key error was:

undefined method empty?' for nil:NilClass

Now I'm combing all over my code to find where I'm using "empty?" but I'm sure it's somewhere that gets run on application startup, otherwise it wouldn't show up when Passenger tries to start the application. But I find nothing and I'm about to shoot myself.

Following the trace I end up hacking Ruby's erb.rb file, as there appear to be some bugs in this; indeed, this one from 1.8.6 is different from what I have in 1.8.7, so the app runs fine here. I try to fix instances where empty? might get called on a nil object, but after fixing 3 of these the app stops responding altogether. Hmm, so something, somewhere, depends on erb.rb's buggy behavior. Best to leave it alone.

HOWEVER, on the deployment server, running with script/server works fine; it's only when using Passenger that things blow up.

Finally I find this thread that points me in the right direction:

One of the users dropped some
JPEG files into the /app/views/static directory, and that seems to be
jamming up the works with 2.2.2.

Indeed, as part of my last set of revisions, I'd left several samples of static content I was converting into dynamically generated pages; sure enough, they included JPGs and whatnot. Just to be safe, I decided to move the entire directory into public to avoid any problems.

Now the app runs just peachy and I only wasted 2 hours chasing down this bug. Thanks to the guys at Nabble!

Eventually it all boils down to this Rails bug reported at Lighthouse. So hopefully it'll be fixed soon. In the meanwhile, keep binary files out of your views subtree.

I'm attaching the entire Passenger error page, in case it's useful to anyone. Mainly so that Google can find it faster for other people with this problem.

Ruby on Rails application could not be started

These are the possible causes:

  • There may be a syntax error in the application's code. Please check for such errors and fix them.
  • A required library may not installed. Please install all libraries that this application requires.
  • The application may not be properly configured. Please check whether all configuration files are written correctly, fix any incorrect configurations, and restart this application.
  • A service that the application relies on (such as the database server or the Ferret search engine server) may not have been started. Please start that service.

Further information about the error may have been written to the application's log file. Please check it in order to analyse the problem.

Error message:
undefined method empty?’ for nil:NilClass
Exception class:
NoMethodError
Application root:
/var/www/spcccdec/releases/20090227005857
Backtrace:
# File Line Location
0 /usr/lib/ruby/1.8/erb.rb 478 in scan'
1 /usr/lib/ruby/1.8/erb.rb 524 in compile’
2 /usr/lib/ruby/1.8/erb.rb 691 in initialize'
3 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/template_handlers/erb.rb 51 in new’
4 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/template_handlers/erb.rb 51 in compile'
5 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/template_handler.rb 11 in call’
6 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/renderable.rb 21 in _unmemoized_compiled_source'
7 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 57 in compiled_source’
8 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 25 in __send__'
9 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 25 in memoize_all’
10 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 22 in each'
11 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 22 in memoize_all’
12 /usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/memoizable.rb 17 in freeze'
13 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 88 in reload!’
14 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 102 in templates_in_path'
15 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 100 in each’
16 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 100 in templates_in_path'
17 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 86 in reload!’
18 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 78 in load'
19 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 109 in load’
20 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 109 in each'
21 /usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/paths.rb 109 in load’
22 /usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/initializer.rb 357 in load_view_paths'
23 /usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/initializer.rb 182 in process’
24 /usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/initializer.rb 112 in send'
25 /usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/initializer.rb 112 in run’
26 ./config/environment.rb 13
27 /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb 31 in gem_original_require'
28 /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb 31 in require’
29 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/railz/application_spawner.rb 254 in preload_application'
30 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/railz/application_spawner.rb 214 in initialize_server’
31 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/utils.rb 179 in report_app_init_status'
32 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/railz/application_spawner.rb 203 in initialize_server’
33 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 166 in start_synchronously'
34 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 135 in start’
35 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 112 in fork'
36 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 112 in start’
37 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/railz/application_spawner.rb 179 in start'
38 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/spawn_manager.rb 222 in spawn_rails_application’
39 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/spawn_manager.rb 217 in synchronize'
40 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/spawn_manager.rb 217 in spawn_rails_application’
41 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/spawn_manager.rb 126 in spawn_application'
42 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/spawn_manager.rb 251 in handle_spawn_application’
43 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 317 in __send__'
44 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 317 in main_loop’
45 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/lib/passenger/abstract_server.rb 168 in `start_synchronously’
46 /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/bin/passenger-spawn-server 46

Piracy in Mexico: Why it won’t stop

A note on Slashdot says “[Nintendo] has requested help in dealing with piracy overseas, both from the US government and from several other countries in particular. China, Korea, Brazil, Mexico, Spain, and Paraguay are listed as the greatest contributing nations to piracy of the company’s products.”

Why are Wii so Expensive?
Why are Wii so Expensive?

Nintendo needs to realize that there’s no way piracy will stop in Mexico unless they lower their prices. A Wii is almost twice as much in Mexico as it is in the USA, costing the equivalent of over 350 dollars here. Games aren’t much cheaper. And Wii Points cards are also twice as expensive here.

It’s also pretty hypocritical of Nintendo. Wiis are plentiful in Mexico, even at times when news of shortages elsewhere were common. The reason is that, since the Wii is so heavily marked up, Nintendo does profit more by selling here in Mexico than in the USA (similar to how they diverted shipments to Europe because higher prices there gave them more profits). However, while there are those mexicans (like me, sadly) who would indeed pay twice the price for the console, which is very convenient for Nintendo, the vast majority of the population can’t afford those prices. So they resort to piracy in order to get their games; buying stolen for their consoles; and (worst of all) buying an XBox instead, because the XBox is 60% the price of a Wii here in Mexico.

This will continue, however hard Nintendo tries to push mexican authorities, because they don’t care; Mexico is a land of impunity, where drug dealers get away with murdering and torturing, often in broad daylight. Obviously the authorities have their hands full and no time for a game company crying wolf because their products are getting pirated.  And anyway, it’s too easy for the “pirates” to bribe the police officers who come to seize their goods and try to arrest them; they, too, are starving and would welcome a few thousand pesos in bribes (or, why not, a shiny new stolen Wii for their kids).

Arrr!
Arrr!

So if Nintendo wants to reduce pirating of their products in Mexico (they can’t stop it altogether), they need to make sure their prices are more in line with what they charge internationally (The USA, specifically). That way more people can afford them legitimately, and there will be less incentive for piracy. However, culturally, legally and politically, the complete erradication of piracy in Mexico is an impossibility. Just ask Microsoft.

EPIC FAIL: the lack of road culture in Mexico City

(c) La Jornada, 2009
(c) La Jornada, 2009

I’ve written before about how people in Mexico have zero road culture, which leads to a complete breakdown of road infrastructure. A lot of this infrastructure’s correct operation depends on people abiding by the law. Yet most people do not. Usually the consequences are from nil (parking in a handicapped space for a moment, leaving your car double-parked, parking in front of a house’s garage) to a relatively minor fine (parking illegally and THEN getting towed because the  tow truck happened to be nearby).

However, when physical security of moving vehicles is dependent on the assumption that people will respect the law, things do indeed break down.

The metrobús is a Bus Rapid Transit system, which opened in 2005 in one important Mexico City avenue, and has enjoyed (in my opinion) great success, reducing transport times, improving traffic flow for private vehicles, and getting rid of dangerous Peseros along Insurgentes avenue. Everybody in Mexico knows Peseros are the worst offenders when it comes to traffic violations, where they blatantly run red lights, invade lanes, and generally do what they please without regard for others. So their sole disappearance was a blessing.

The price to be paid for this was that, since the metrobus runs on central lanes, left turns are forbidden along the avenue’s 26-km length. The reason is obvious: at the very least a significant disruption of traffic might occur if the bus has to stop for a car that’s trying to left-turn. At worst, the metrobus, a double-length behemoth, might hit another car with deadly consequences.

It’s been 3 years of the Metrobus operating, and this year a second line (running along eje 4 sur) was opened. This has caused an uproar because it appears this line has been misdesigned, creating several “death traps” and spots where, due to lack of space, cars and pedestrians have a tough time getting through. This has led to 18 accidents since the new line opened.

Some asshole in the government who needs urgent math lessons said that “98% of accidents involving the metrobus are due to private car driver’s imprudence”. For starters, 98% of 18  is 17.64, and assigning partial blames is absurd.

Anyway, what’s indeed clear is that most of the accidents are due to lack of culture by drivers. The all-too-common notion that “nobody wants to have an accident and if I just swerve violently in front of someone they’ll stop and swear at me but I’ll get my way” fails when the “someone” is a 15-ton monster  traveling at 60 km/h with 30-meter stopping distances.

Sometimes, then, images are worth a thousand words, so I’ll leave you with the conclusion that while it’s necessary to guarantee that people operating a car need to have a minimum of road education, it’s also not going to happen because the “it’s ok just this one time” mentality rules, and as long as we’re giving driving licenses to anyone without a driving test (right, in Mexico there are no driving tests, you just pay for your license and you get it) things like this are going to happen. I also leave you with an eye-opening video of exactly whose fault it was for the accident, a picture of which is at the top of this message.