RubyConf India 2010!

Posted by Nick Sieger Fri, 12 Mar 2010 23:21:04 GMT

I’m honored to be heading to the first ever RubyConf India in Bangalore next week. I’ll be delivering an update on Rails 3, JRuby, and what’s in store for the future of the combined platform in 2010. I’m looking forward to meeting you there!

I'm speaking at RubyConf India 2010

Tags , ,  | 2 comments

Gem clash: activerecord-jdbc-adapter and pg

Posted by Nick Sieger Thu, 28 Jan 2010 15:16:49 GMT

I got a note from a community member about an annoying problem that a few people have run into when installing activerecord-jdbc-adapter (AR-JDBC) into a C Ruby implementation:

NameError: uninitialized constant
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::PGconn

Turns out it’s pretty easy to momentarily forget to use jruby -S gem or jgem and just gem install activerecord-jdbc-adapter and suddenly your pg Postgres gems are not working properly. I thought it was worth documenting here in case others run into this problem.

I apologize for the clash. I had to provide a stub pg.rb in AR-JDBC inside of JRuby so that I could get active_record/connection_adapters/postgresql_adapter.rb to load with a database adapter type of postgresql. Because of load path order issues, I couldn’t get AR-JDBC’s code to load before ActiveRecord’s. At the time I was thinking this wouldn’t be a problem because the pg library won’t work on JRuby anyway, right? Wrong.

I can think of a couple options going forward:

  1. Submit a patch to ActiveRecord so that active_record/connection_adapters/postgresql_adapter.rb can load without requiring pg up front and then AR-JDBC won’t have to stub it out.
  2. Display a big fat warning message when AR-JDBC is installed into anything other than JRuby.

Any other thoughts?

Tags ,  | 2 comments

New Hpricot Release

Posted by Nick Sieger Fri, 06 Nov 2009 16:06:37 GMT

It’s with a modicum of fanfare and a cocktail of orange peel, maraschino, bitters, bourbon and vermouth that I announce the 0.8.2 release of Hpricot.

hpricot

The angly thingies are just two martini glasses turned on their side, see? Pouring out hpricoty goodness for you. (I don’t know if _why imbibed alcoholic beverages but I feel the desire to raise a glass to him.)

This release is mostly a refresh; the previous release was way back in April. From the Git logs I can see that there were a few bug fixes since then. Otherwise, the main addition is a modern JRuby release, thanks to Ola Bini. (the previous was the 0.6 series). This does fix a fairly old, popular JRuby bug.

As for the future of Hpricot, it’s up to you. I know it’s still a trusty tool for many; I have no grand plans to change it. So if you encounter bugs and want to send patches, I’m happy to serve as your curator.

Tags , , ,  | 2 comments

Which Tool Would You Use?

Posted by Nick Sieger Fri, 12 Jun 2009 20:34:27 GMT

I started in on the twice-yearly task of pruning our hedges today. So confronted with this task:

Shearing the shrubs

Which tool would you use?

Which tool?

I used both today, but realized I enjoy using the hand trimmers much more. With the electric trimmers, you can buzz through a lot of hedge quickly, but sometimes this happens:

Too close

With the hand trimmers, I can take my time and make precise cuts. The end result may take more time, but it turns out much, much better.

Software tools have similar feels to me. Java feels an awful lot like the electric trimmers. It’s heavy and powerful, but sometimes by the time you’ve finished with it, you’ve cut so far in that you may have missed a simpler, lighter solution.

Ruby feels like the hand trimmers. Precision, less code, more intent, and I can take my time to think through and arrive at a solution without leaving a huge trail of trimmings (code) behind me.

Tags  | 4 comments

Three Years of JRuby on Rails

Posted by Nick Sieger Wed, 13 May 2009 21:21:37 GMT

Just yesterday the 3-year mark of JRuby running Rails passed by. In the intervening period since JRuby first started to run Rails, we’ve seen:

And yet, JRuby still has plenty of untapped potential and room for growth and adoption: in the existing Ruby and Rails communities where JRuby is showing promise as a stable, performant, concurrency-enabled, and leak-proof platform; and as a transformative force to capture the mindshare of a huge army of Java developers who aren’t even aware that there’s a language and runtime that allows them to preserve their skills and existing code while developing new applications faster and with much greater enjoyment.

Here’s looking to the future of continued growth for JRuby over the next three years. The best is yet to come!

Tags , ,  | 4 comments

My Article for Ruby Advent 2008

Posted by Nick Sieger Fri, 19 Dec 2008 05:04:00 GMT

I wrote an article for Ruby Advent 2008 about using JRuby, RMagick4J, Gruff, and JMX to create a simple JVM memory monitoring application. Go check it out and let me know what you think.

I’ve also posted the source for the article.

Happy Holidays!

rubyadvent

Tags , , , ,  | 1 comment

QCon: Interviewed by Fabio Akita

Posted by Nick Sieger Mon, 24 Nov 2008 18:51:00 GMT

Fabio Akita played the role of the Energizer Bunny, making a blur around the hallways at QCon. He managed to catch me on Thursday morning, and we had a great chat.

Fabio Bunny

Go check out our conversation on Akita On Rails to hear my take on JRuby and Rails 2.2 and more. Thanks for doing the interview Fabio!

Tags , , ,  | no comments

QCon Wrap-up: Enterprise, Have You Met Ruby?

Posted by Nick Sieger Sun, 23 Nov 2008 08:51:03 GMT

This year’s QCon San Francisco conference was my first time attending, and it was an eye-opener for me for several reasons.

First, the tutorial Ola and I gave on Monday went well, though I was mildly surprised to find that only about 10% of the attendees at our talk had any familiarity with Ruby. This turned out to work just fine as we were able to adjust and fill in a little bit of the back story on both Ruby and Rails. Still, to try to convey a sense of Ruby, Rails, and JRuby all in the span of a 2.5 hour session is a tall order!

Next, I was impressed with the diversity the conference organizers were able to achieve. There were tracks on agile development, cloud computing, REST, DSLs, design and clean code, Ruby, functional programming, real-world architectures, storage rethinking, and more. Tracks were relevant and topical even if the quality of talks was mixed.

The last item relates to my perception that Ruby is not yet seen as a worthwhile tool for enterprise software development. It leaves me with some cause for concern, though it reflects more on the state of the industry rather than on the way Ruby was presented at the conference itself.

What does it mean for Ruby to be “ready for the enterprise”? Does that imply JRuby? Running on the JVM or a Java application server, or even .NET? Reams of XML? Presence of buzzwords, such as JMS, Spring/Hibernate? Or ability to adapt to or leverage legacy code? All of these?

I would argue that Ruby already has everything it needs to be a successful enterprise software development platform, even without using JRuby. Ruby has a mature standard library, a large and ever-growing list of gems and extensions, and a vibrant community. Testing tooling, certainly seen more and more as a critical piece of software development, is also an area where Ruby excels (and brings a strong culture bias toward testing as well). Add JRuby to the mix and the ability to leverage existing infrastructure as well as code, and the picture gets even stronger. Best of all, Ruby the language is a malleable medium perfectly suited for gluing enterprise components together, creating DSLs on top of stable layers and remaining clean enough to be eminently readable and maintainable. Yet behind-the-firewall deployments appear to be elusive; if they do exist, they’re small, isolated apps that work so well, the community doesn’t hear about them. Judging from the low level of participation in Ruby-related talks at QCon, I’m inclined to believe the former.

I was speaking with Jay Fields about this topic on Friday. Jay also noticed that the the Ruby and DSL tracks were sparsely attended. (For that matter, so was the functional programming track.) His observation was that the track content was not marketed and tailored enough toward toward solving enterprise-class problems, or being approachable enough in that regard. We can certainly do better.

Do we have an issue here? Are we, the Ruby community, being too insular and not concerning ourselves enough with bringing Ruby-based solutions to the enterprise? Or perhaps businesses are waiting for more organizations that can provide services, support and indemnification? Does there need to be a Ruby, Inc. (or even a JRuby, Inc.) that looks at common enterprise problems and devises best-of-breed solutions (a sort of SpringSource for Ruby) for things like enterprise integration, security and identity, reporting, business workflow, decision support, etc. ad infinitum? Ruby should be able to do all of those while bringing the increased agility and productivity that we’ve all experienced.

I seem to have raised more questions than I am able to answer at this time. Of course, the obvious answer is that adoption of Ruby will just need more time, but I’m not willing to accept that as the only reason. I’d love to hear your opinions on contributing factors and what can be done to mitigate them. It seems like there’s a huge opportunity waiting to be tapped to help make Ruby more enterprise-worthy.

And yet, despite the less-than-stellar turnout for Ruby at QCon among conference attendees, I still had a great week, and would go back again. QCon is a fun and well-organized event overall, and I got the impression that the folks present were on the leading edge of “the enterprise”, which is exactly the people we need to engage to bring about growth in adoption of Ruby. For that reason, I hope we can kick it up a notch and take another shot at pimping Ruby at the next one. Maybe I’ll see you there!

Tags ,  | 12 comments

ImageVoodoo 0.1 Released

Posted by Nick Sieger Thu, 27 Mar 2008 21:39:23 GMT

Introducing ImageVoodoo

I just pushed out the first release of ImageVoodoo, a nifty little image manipulation library conceived as a quick hack by Tom. It’s a play-on-words of ImageScience, of course, the quick, lightweight imaging library for Ruby. To get it,

jruby -S gem install image_voodoo

What’s cool about ImageVoodoo (other than the name) is that we were able to make it API-compatible with ImageScience. In fact, ImageVoodoo’s image_science.rb simply looks like this:

require 'image_voodoo'
# HA HA...let the pin-pricking begin
ImageScience = ImageVoodoo

So, you can use it pretty much anywhere you might use ImageScience, and it should just work. At work, we’re using it with attachment_fu, and it works great. ImageVoodoo even steals and uses ImageScience’s unit tests (which all run successfully, too). Speed-wise, it’s about twice as slow as ImageScience running on MatzRuby, but still plenty fast enough for most cases.

But we wouldn’t be having fun unless we embraced and extended a little bit, right? So I added a couple of extra features you might find useful.

Preview

Since ImageVoodoo is just leveraging the Java Platform’s imaging libraries, image rendering can be easily tied into a simple preview frame. This code:

ImageVoodoo.with_image("samples/checkerboard.jpg") do |img|
  img.preview
end

Will pop up a little frame like this:

preview

The code that displays the preview frame is nice and compact, and shows off how nicely you can write clean swing GUI code using JRuby’s java integration features.

class ImageVoodoo
  class JImagePanel < javax.swing.JPanel
    def initialize(image, x, y)
      super()
      @image, @x, @y = image, x, y
    end
    def paintComponent(graphics)
      graphics.drawImage(@image, @x, @y, nil)
    end
  end

  class WindowClosed
    def initialize(block = nil)
      @block = block || proc { java.lang.System.exit(0) }
    end
    def method_missing(meth,*args); end
    def windowClosing(event); @block.call; end
  end

  def preview(&block)
    frame = javax.swing.JFrame.new("Preview")
    frame.add_window_listener WindowClosed.new(block)
    frame.set_bounds 0, 0, width + 20, height + 40
    frame.add JImagePanel.new(@src, 10, 10)
    frame.visible = true
  end
end

Command-line

As I was fixing a bug in ImageVoodoo’s file saving I whipped up a little command-line utility to aid debugging. It allows you to string along several image manipulation actions on a single command-line. For example,

jruby -S image_voodoo --push --resize 50x50 --preview --save t1.jpg \
  --pop --resize 40x40 --preview --save t2.jpg \
  --pop --resize 30x30 --preview --save t3.jpg image.jpg

This will resize image.jpg into three smaller images, t[1-3].jpg, but will pop up a preview frame at each step of the way. Simply close the preview frame to continue to the next action, or quit out of the application to abort.

Summary

And so, another functional area, image manipulation, becomes as easy on JRuby as it is on MatzRuby. Now that fancy social networking application you’ve been working on should have one less reason to be able to run unmodified on JRuby!

Tags , , , ,  | 3 comments

Monkey-patching is Part of the DIY Culture

Posted by Nick Sieger Fri, 14 Mar 2008 00:07:00 GMT

Recently there was a long (122 posts!) thread on Ruby-talk started by Avdi Grimm (based on a post he made on his blog). He took a risk by titling the post “Monkey-patching is Destroying Ruby,” which got a lot of attention but probably ruffled a few too many feathers before he had a chance to justify his argument.

I don’t disagree with Avdi’s main point, which is that monkey-patching isn’t always the best tool for the job. But I contend that it’s still a basic part of the Ruby programming culture, like it or not. I believe the reason for this is that monkey-patching is an extremely empowering technique. It’s part and parcel of the hacker/DIY culture.

Anyone who has had an experience in a less-flexible language or caught in a hard place trying to debug a closed-source library can appreciate how liberating it is to take matters into your own hands, fix your own problem, and to be able to do it without modifying the original library source. It’s a revelatory experience that makes you never want to go back to inflexible programming environments ever again. There’s also nothing wrong with monkey-patching a library you don’t control as long as you freeze all the code you’re using before making a working patch – if your patch works and you don’t change or upgrade anything, you’re not likely to encounter any problems.

Of course all monkey-patches are not created equal. Some are certainly more onerous than others. Let me give you an example I ran into myself recently, which raises some questions for which I don’t yet have the answer myself.

The most prolific Rick Olson’s popular plugin attachment_fu uses Ruby’s tempfile library. It has a legitimate need to extend Tempfile to preserve the file extension on tempfiles, so that image conversion routines can use the file extension to help identify the format. How it accomplishes this, however, is not very pretty. Here’s the original Ruby code (as of Ruby 1.8.6 p111):

def make_tmpname(basename, n)
  sprintf('%s.%d.%d', basename, $$, n)
end
private :make_tmpname

Seems like about as reasonable a place as any to hook in, right? But the method is marked private – I’m guessing the original implementor (according to svn blame, it appears to be Akira Tanaka) probably did not intend for the method to be replaced. But, hey, it’s Ruby, right? So away attachment_fu goes:

Tempfile.class_eval do
  # overwrite so tempfiles use the extension of the basename.  important for rmagick and image science
  def make_tmpname(basename, n)
    ext = nil
    sprintf("%s%d-%d%s", basename.to_s.gsub(/\.\w+$/) { |s| ext = s; '' }, $$, n, ext)
  end
end

As far as monkey-patches go, this isn’t too bad. There is no code copied from the original implementation, and it’s a fairly focused and compact method. The fact that it’s private is a bit of a smell, though. But, it works, and we forget about it happily (if we even knew it existed in the first place), and hope that tempfile.rb never changes.

Well, in my case, it did. MenTaLguY has been working on more robust, thread-safe versions of the standard libraries. And he changed the arity of make_tmpname:

@@sequence_number = 0
@@sequence_mutex = Mutex.new
def make_tmpname(basename)
  begin
    File.open("/dev/urandom", "rb") do |random|
      "#{basename}.#{random.read(16).unpack('H*')}"
    end
  rescue
    # insecure fallback
    sequence_number = @@sequence_mutex.synchronize { @@sequence_number += 1 }
    "#{basename}.#{$$}.#{sequence_number}"
  end
end

Resulting in:

Read error: #<RuntimeError: cannot generate tempfile `': wrong number of arguments(1 for 2)>
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/1.8/tempfile.rb:39:in `initialize'
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-java/lib/mongrel/http_request.rb:47:in `new'
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-java/lib/mongrel/http_request.rb:47:in `initialize'
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-java/lib/mongrel.rb:149:in `new'
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-java/lib/mongrel.rb:149:in `process_client'
/Users/nicksieger/Projects/jruby/trunk/jruby/lib/ruby/gems/1.8/gems/mongrel-1.1.3-java/lib/mongrel.rb:285:in `run'

So, it took me a while before it occurred to me that something in my project might be overriding make_tmpname. But even after I found it, notified MenTaLguY, and he fixed it, it still left me wondering: who’s in the wrong here? Akira-san, for not making a better way to hook into make_tmpname, Rick for monkey-patching it, or MenTaLguY for changing the method arity in his rewrite? I can’t really point the blame at any of them.

There are certainly more egregious and offensive monkey-patches than this example (and I include myself in that camp). In any case though, I could live with just about any monkey-patch if I had better debugging tools. For example, it would be great if you could ask Ruby to track and retain references to all methods, including those that get replaced, along with the source locations where each was defined. Another possibility might be a before_method_added hook that could let you track method replacements as they’re about to happen (and maybe even veto method redefinitions!).

These are the types of tools that an enterprising Ruby programmer could look at adding to any one of the existing Ruby implementations. Both JRuby and Rubinius are becoming test beds for bleeding edge features that could help advance the state of the art. So pitch in and help make monkey-patching less painful!

Postscript: This post coming to you from the Illinois interstate courtesy of Curt and his 3G EVDO wi-fi hub!

Tags  | 2 comments

Older posts: 1 2 3 ... 5