RVM, Zsh and Konsole

Today I set up RVM with Zsh (Z shell) with Konsole (the KDE equivalent to gnome-terminal).

The RVM Konsole example shows it with bash, setting the “Command” field to “/bin/bash –login”. The line for Zsh is nearly the same: “/usr/bin/zsh –login”.

If you don’t have this, you’ll get the error:

% which ruby
/usr/bin/ruby
% rvm use 2.0

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.

Note that you’ll need to have RVM as the first component in the PATH (“echo $PATH”).

With the “Command” field set to “/usr/bin/zsh –login” (that’s “dash dash login”), when you start a new terminal you should get:

% which ruby
/home/jpace/.rvm/rubies/ruby-1.9.3-p551/bin/ruby
% rvm use 2.0
Using /home/jpace/.rvm/gems/ruby-2.0.0-p598
% which ruby
/home/jpace/.rvm/rubies/ruby-2.0.0-p598/bin/ruby

sort{ |a, b| a <=> b }.ing with Ruby

One idiom from Perl that I’ve missed with Ruby is the ability to chain comparisons together, such as:

my @a = qw{ this is a test };

$, = ", ";

print sort { substr($a, -1) cmp substr($b, -1) || length($a) <=> length($b) } @a;
print "\n";

Which results in the output:

a, is, this, test

In Ruby, it’s a little more complicated, since Perl evaluates a zero as false, but Ruby does not. However, the nonzero? method for all Ruby Numeric objects essentially performs this conversion, for use in a boolean evaluation, returning nil if it is zero, and the number otherwise. So in Ruby, the above code would be:

a = %w{ this is a test }

puts a.sort { |a, b| (a[-1] <=> b[-1]).nonzero? || a.length <=> b.length }.join(", ")

One additional note: if you’re using this in a spaceship method (“”) for the Comparable interface, remember that it must return a numeric value, so if you chain evaluations together, the final statement should be zero, since all previous evaluations were nil (meaning that they were equal). This bit me during some recent DiffJ work, and here is an example of a corrected method:

class Java::net.sourceforge.pmd.ast::Token
  include Comparable, Loggable

  # ...

  def <=> other
    (kind <=> other.kind).nonzero? ||
      (image <=> other.image).nonzero? ||
      0
  end

That’s DiffJ opening the PMD token Java class and adding the Ruby Comparable interface to it, so tokens can be sorted in Ruby collections.

On that note, DiffJ is in rough beta status now. I’m using it for my work (refactoring and cleaning up legacy Java code), and just corrected a glitch in the Token code, ironically enough, for supporting usage in Hash objects. I’d neglected to implement the eql? method, erroneously thinking that Hash uses the Comparable code.

With that fix, the JRuby implementation of DiffJ produces the same output as the Java implementation. It’s somewhat slower, so I’ve been investigating AOT compiling of it, but that doesn’t seem to have much of an effect.

I just realized that another feature from Perl that I’ve missed (and until writing that code above, hadn’t used for 10 years) is defining the array separator with the “$,” variable. Similar to that, my RIEL library modifies the to_s method of an Array to output “, ” between elements for output, since the default is to have no space between elements.

Timelessness of Quality

I’ve been rereading Hackers and Painters, by Paul Graham, and his chapter on Lisp was especially interesting, given that I’ve been working on expanding my Emacs knowledge and further refining my environment.

The connection between Lisp and Emacs? In this sense, they both became the standard-bearer for their field (programming languages, text editors), and reached that point very soon after the inception of the field. Each of them was so far ahead of the others that even decades later, one could argue that neither Lisp nor Emacs has been matched. If anything, progress in the fields has just been that the mainstream (meaning, widely accepted) products are more and more like Lisp and Emacs.

This doesn’t seem atypical, that there is this quantum leap early in the field. Among guitarists the Gibson Les Paul and Fender Stratocaster are probably the two most popular electric guitars, even a half century after their initial release in the late 1950s, when the electric guitar originated. In my non-expert vantage point I don’t perceive a fundamental difference (as in performance and function, not appearance) between the newest guitars now and the original Strat and Les Paul.

As Graham does, the same argument could be made for Ruby and Lisp, that of “modern” programming languages, Ruby is one of the closest to Lisp in terms of functionality (although its form is somewhat different). About Emacs, I don’t know what other text editor could be considered close, but it seems that Emacs is the most imitated – for example, it seems that the Eclipse editor is much closer to Emacs in behavior than it is to, say, vi. (On that note: is any other text editor similar to vi?)

It seems that the cycle is somewhat like this: the field originates, there are a few competing lead products, one dominates clearly, then there are relatively few imitators for the next decade or two (or more). After a while, the imitators become better and more like the original, to the point that they are essentially just re-badging it.

I’ve tried several times to really learn Lisp in the past, but had difficulty hurdling the syntax, probably in part because of my background in C, Perl, C++ and Java. But having now read of the similarities between Lisp and Ruby, I’m eager to see the difference in my perspective as I go through the excellent Emacs and Emacs Lisp tutorials at Xah Lee’s Emacs Blog).

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.

JRuby and Rake

In my quest to write nothing but Ruby code in my copious free time, I’ve begun learning JRuby, which I’m finding an ideal solution to my Java projects, such as DiffJ and DoctorJ, which are dependent on Java because they use the parser from PMD.

Likewise I am migrating my build code away from Ant, using Gradle for the soon-to-be-released DiffJ 1.2.0. Thus I began trying to use the Ant library for Rake via JRuby, but was confounded by an error for the simple Rakefile:

require 'ant'

task :greet do
  puts "hello"
end
% jruby -S rake /usr/bin/rake:27:in `require': no such file to load -- rake (LoadError)
	from /usr/bin/rake:27

The fix was simple. Changing my mindset was more complicated: JRuby is looking for Ruby Gems in its own directory hierarchy, not the Ruby hierarchy.

So installing the Rake gem as follows fixed the problem:

% sudo jruby -S gem install rake