Replacing Asus K50IJ Keyboard

Other than replacing and upgrading memory, I’ve never done any hardware work on laptops, but today I finally replaced a laptop whose keyboard had been molting for a while, losing four of its keys.

Buy.com had a replacement keyboard here for $20.

So with keyboard in hand, it was time to replace the old one. It was easy enough to find instructions online, but several links returned by Google for “replacing laptop keyboard asus k50ij” had misleading and incorrect directions, or seemed to be simply generic templates for laptop keyboard replacement, but not specific to the Asus K50IJ.

This site had the most accurate and thorough information, including annotated photos, making it (literally and figurative) a snap to install the new keyboard, in just a few minutes.

Now, back to coding, and to wondering why Gradle does not seem to apply exclude patterns during compilation, and thus complains about Emacs temporary files being unreadable files.

JRuby Issue with Regexp.last_match

In the DoctorJ project, I’ve been rewriting the Javadoc parser, and did the initial rewrite in Ruby. That was straightforward, and I then began migrating that to JRuby, with the idea that the code could gradually morph from Ruby to Java, via JRuby, such as regular expressions being reimplemented as java.regex.Pattern instead of Regexp.

The first step of the Ruby to JRuby transition was simply to change the shebang line to “#!/usr/bin/jruby”. However, there were test failures, and finding the source of those failures was difficult because the tests were so high level, meaning that the parsed Javadoc is what was tested, not the results of processing the Java comment with the Javadoc regular expression.

Eventually it became clear that the issue was with JRuby itself, not with my code. The JRuby code is very clear to understand and is formatted very well, and it closely matches the C source code of Ruby itself, making issues even easier to diagnose.

In this case, the issue was with the RubyRegexp class in JRuby, which, when setting the value that Regexp.last_match will return, has a reference to the region (capture/group) for the current match. However, that reference is to a “live” object (as opposed to an immutable one), and subsequent matches for that regular expression will update the region object, so the first Matchdata returned by Regexp.last_match will have captures that are the same as the latest match.

Here is a RubySpec that describes this issue:

describe "JRUBY-6141: Matchdata#captures" do
  before :all do
    "first, last".scan(Regexp.new('(first|last)')) do
      @firstmatch ||= Regexp.last_match
    end
    @lastmatch = Regexp.last_match
  end

  it "returns first value from Regexp.last_match after all String#scan iterations" do
    @firstmatch.captures[0].should == "first"
  end
  
  it "returns last value from Regexp.last_match after all String#scan iterations" do
    @lastmatch.captures[0].should == "last"
  end
end

The solution for this issue is that the Region object should be cloned for setting the Regexp.last_match reference.

This issue was submitted as JRUBY-6141. JRuby uses RubySpec, so I provided the above test, as well as a Git patch, which were committed to the JRuby source.

… and Back to Gnome from KDE

I recently switched from Gnome to KDE, after a couple of Gnome quirks proved to be quite irritating. However, KDE became even more bothersome. Specifically the performance was dreadful. This is a new(ish) machine, just a few months old, with a six-core processor, 8 GB of memory, and an SSD, so I expect good if not extraordinary performance. However, under KDE the response within windows was very sluggish, on the order of a second or two to scroll down in applications.

Fonts were also a problem, where the fonts under KDE, for both KDE and Gnome applications, lacking smoothness. Despite much fiddling of font preferences, I could not get them to look as good as they do under Gnome.

Switching back to Gnome hasn’t resolved its irritations, although it’s put them in context. The main problem is that to get the title and task bars working properly (showing the currently focused application) I have to restart the window manager after login, and after launching Gnome Terminal I have to switch in and out of each tab so that the focus of the cursor is correct.

Getting Started with JRuby

I was asked to summarize my experiences with starting up a project with JRuby, so I’ll do so here.

My experience with JRuby is only a couple of months, doing two projects, Armitage and Mackworth, two graphically-oriented psychological testing programs.

Overall I have been very impressed with JRuby, which I’m finding to be an excellent way to leverage the cleanliness of Ruby code with Java libraries, in my case, Swing, in the above two projects. I am also working on prototyping the new Javadoc processor for DoctorJ, writing it with a regular expression in Ruby, which I will migrate over to pure Java, but one chunk of code at a time via JRuby. My earlier rewrite went poorly, since without using JRuby as a bridge, I had to convert Ruby code straight to Java, which was too drastic of a change to go well. And it didn’t.

JRuby is so much like Ruby that the differences are surprising. As I wrote before, Ruby gems are not JRuby gems. Java threads behave poorly with Ruby threads, and I found it easier to use only Java threads.

In Swing, there are issues setting a JFrame as full-screen via the extended state and undecorated attributes, such as (in a subclass of JFrame):

    set_extended_state JFrame::MAXIMIZED_BOTH
    set_undecorated true

In Linux, this works properly in Java 1.6, but not in Java 1.5. In Windows, it does not work correctly with neither Java 1.5 nor 1.6.

Distributing a JRuby program is easy, although I wish (as with many programming languages and environments) that an installer was more integrated with the language. The best solution I found was to jar the complete JRuby jarfile with my *.class and *.rb files, with the manifest (META-INF/MANIFEST.MF) contents as “Main-Class: MyAppMain”.

MyAppMain is the JRuby equivalent of the Java main class, annotated as a Java class, such as:

    class MackworthTestMain
      java_signature 'void main(String[])'
      def self.main args
        MackworthTestFrame.new
      end
    end

Building a JRuby application is easy via Rake, and my Rakefile for Mackworth can be found here. In this file is the code common to it and the Rakefile for Armitage.