Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

2.12.2008

Making IRB work properly under Windows when using an international keyboard

Until today, I've been looking for a way to solve a problem I have running irb under Windows. The problem is that I'm using an international keyboard layout and keys like [, ], { and } (which are really useful in Ruby) could not be inputted in irb when readline is enabled.

I did some research on the web, but the solution did not worked for me (and it looks like I'm not the only one). A few weeks ago, I stopped looking for a solution as I decided to do my RoR work on a Linux Virtual machine. For some reason, I had to start working on Windows again. So today, I decided to dig a bit deeper. As the proposed solution used an .inputrc file, I investigated the format of the file and came across a post that described a problem using the Meta key shortcut (M-) in a .inputrc file. The response to the problem suggested to use "\e" instead of "M-". So I did that and guess what? it worked!

So putting everything together :

  1. Add the HOME environment variable => HOME=%USERPROFILE%
  2. Create a .inputrc file in your home folder (cd %USERPROFILE%) with the following content :
  3. "\e[": "["
    "\e]": "]"
    "\e{": "{"
    "\e}": "}"
    "\e\": "\"
    "\e|": "|"
    "\e@": "@"
    "\e~": "~" 
  4. For added completion/history management, create a .irbrc file in your home folder with the following content:
  5. require 'irb/completion'
    ARGV.concat([ "--readline", "--prompt-mode", "simple" ])
    
    module Readline
      module History
        LOG = "#{ENV['HOME']}/.irb-history"
    
        def self.write_log(line)
          File.open(LOG, 'ab') {|f| f << "#{line}\n"}
        end
    
        def self.start_session_log
          write_log("\n# session start: #{Time.now}\n\n")
          at_exit { write_log("\n# session stop: #{Time.now}\n") }
        end
      end
    
      alias :old_readline :readline
      def readline(*args)
        ln = old_readline(*args)
        begin
          History.write_log(ln)
        rescue
        end
        ln
      end
    end
    
    #Readline::History.start_session_log
    
    require 'irb/ext/save-history'
    IRB.conf[:SAVE_HISTORY] = 100
    IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
And you're done!

2.04.2008

Chased by the statically typed ghosts

It looks like statically typed ghosts are out there again. They like to chase the Poor little dynAmiCally typed Man. Most of the time, the ghosts run faster than the little Pac-Man but their bloat makes them crawl when they turn corners or go in tunnels. Little Pac-Man goal is to clear the level in the most efficient way. Little Pac-Man has some special features to help him mind his business. For each level that he has to go through, he can use specials pills. These pills allows him to open up the ghosts and mixes in some different behaviour into the ghosts. De-routed by this ability, the ghosts turns blue. Little Pac-Man understand that this power comes at a certain price, this is why he uses it sparingly and do not abuse it to eat the ghosts (unless he knows he can eat them all in one shot as this will make him score big-time!) as they will quickly return to their static behaviour. As we can see in the picture, it takes four (4) ghosts to take on Pac-Man.

5.02.2007

RE: To Groovy or to JRuby

Shay Banon ask the question : To Groovy or to JRuby?
It seems that these days, whenever we see Groovy mentioned in blog post, it must be compared to Ruby or more specifically to JRuby. Then, in the comments, we have some Groovy lover express that Groovy is better than JRuby for the Java developer. What is funny is that people who are working on JRuby suggests that you try both and see for yourself.

Now that Groovy achieved to deliver a 1.0 version (and now a 1.1), it seems that this trend is increasing... Groovy advocate are becoming more vocal about their stuff. Instead of pushing Groovy/Grails for what it's worth, they are pushing it by saying how easy it is to learn compared to Ruby/Rails for a Java developer perspective. This is the argument that's being repeated over and over! And, as we see in some post comments, this makes some manager feel better.

This makes me feel sad!

Now this argument has some truth in it, but this does not necessarily make Groovy a better alternative than JRuby for scripting the Java platform. Learning a new language is always a good thing... Be it Groovy, Ruby, Python, etc. You never really loose by learning a new language... You never really loose by learning a new API, a new framework. Learning new things makes you a better programmer.

This is why I prefer Ruby/Rails than Groovy/Grails... It's not because Ruby/Rails is superior, it's just that learning a completely new language/framework help me open my mind to new ways of thinking. Learning Groovy will also do that, but to a much smaller extent. This will help me become a better programmer... Even better it will keep my mind awake enough to not become a dinosaur who know only one language/framework.

And to the manager that may read this... Having developers who have an open mind and bring new ideas is way better than having developers that will not stray away from their main comfort zone. It cost less in training and allow you to get advantage of new technologies as they become mainstream instead of missing the boat.

Don't take this post as telling you to choose JRuby, like Charles Nutter said, "don't let anyone make the choice for you."



3.23.2007

Grails vs Rails... The number game just started!

A first Grails vs Rails Performance benchmark has just been published The benchmark shows that Grails is faster than Rails. Rails developer Jared Richardsons commented on some flaws with the benchmark (aren't all benchmarks flawed in some way? And as the benchmark author said, the benchmark is not about scalability).

But looking at these numbers, I found that Rails is not far behind Rails. And I find that very encouraging for the Rails community. Yes, I would expect much better performance on the Grails side... Most of Grails is Java code. Java code running inside a modern JVM should run pretty fast. But beside the insert test (which I guess is significantly slower due having just one Mongrel instance running), Grails is not very far ahead Rails. Rails is mostly Ruby code. The Ruby interpreter is just that, an interpreter. There is no just-in-time compilation, no enhanced optimization for often used code in Ruby.

I can't wait till we have Ruby running on some VM (maybe the JRuby team will run the same benchmark and give us their numbers) and I guess we will see some great improvement on the Rails side (I guess that just rerunning the benchmark with multiple Mongrel instances will close much of the current gap).

This may be the very start of the Grails vs Rails number game!



3.15.2007

JRuby on Grails?

There is a small ongoing debate about Ruby on Grails... the Grails founder, posted in thoughts on the topics too.

I don't know were Graeme takes it's numbers about Grails apps that are in production, but I guess that Ruby on Rails numbers are much higher. He argue that for a Java shop, Grails is much better framework than JRuby on Rails. His main argument to support this is that it will take less training. He seems to forget that to learn Grails (even if it's closer to Java than Ruby) also require some training. I would even add that learning the convention for framework like Rails or Grails is where most of the training is required... Learning the language is easier than learning the conventions.

In my point of view, JRuby on Rails has much more potential than Grails. First, Grails is playing catchup with Rails (still waiting for Migration in Grails). Second, Grails biggest strength reside on the integration layer between well know frameworks. However, these same frameworks are Java based and they come with the same limitations that the Java language has. Limitation that are not present in Rails because of the dynamic nature of the language it's build on.

Why would it be a good idea to run Rails on JRuby? Yes, integration with Java is a plus. But performance may be part of the answer. Ruby is not very fast (but it should get a lot faster very soon with the use of a Ruby VM), Java is quite fast. So running Rails on Java can make it faster. Even with Ruby VM coming along, JRuby may be faster because Java VM had a lot more work done in the VM performance than Ruby will have when it get it's own VM. If I'm able to run a Rails app in Tomcat or Weblogic, it will also have more appeal for existing Java shops. It could also give you the benefit of having access to existing Java libraries that have no equivalent in the Ruby world.

Instead of working on making JRuby as a language to run on top of Grails, if integration with existing libraries (like Hibernate) is desired, I think that Integrating the existing library in Rails would be much better. One could easily write a simple layer around Hibernate so one could have model objects inheriting something like HibernateRecord instead of ActiveRecord. The dynamic nature of Ruby could make this HibernateRecord behave the same way as an ActiveRecord. As for presentation framework, I don't think that component-based framework are such a good idea anymore. So there is no need to ever want to integrate them in Rails.

Graeme argue that Sun should not longer put resources in Phobos because the project is unpopular... I could argue that same thing about Grails... Compared to Rails, Grails looks like the unpopular guy in the schoolyard. But I won't do that... While I personally don't see why would someone would choose Grails over Rails, I thing that competition between frameworks is good. And when Grails will start to innovate (instead of playing catch-up) then it may become really interesting. The unpopular guy of today can always become the most popular guy of tomorrow (this is the Ruby and Java story).


1.24.2007

j2ee_util.rb public release

I just released my first public version of j2ee_util.rb : Simple tool to manage your J2EE archives (war, ear, jar, zip). Not long ago, I had to make quick changes in a web.xml file contained in a WAR file contained in an EAR file. To do that, I had to extract the EAR that extract the WAR then edit the file then repackage everything.

The process is a bit cumbersome and prone to errors. Yet, I never saw a command-line utility that allows one to do that. So I decided to write my own and j2ee_util.rb was born.

With this command line tool I can now type this to edit the web.xml file :
ruby j2ee_util.rb --edit my-application.ear:webapp.war:WEB-INF/web.xml

And when I exit the editor, the file is automatically repackaged in the WAR file which will be repackaged in the EAR file. The tool also only extract the specified files instead of the whole archive.

I plan to add a few features to be able to edit stuff directly from the command-line (like replacing a value in an XML file) without having to fire-off an editor.

If you use the tool and have any comment/idea/issue with it, fell free to leave a comment on this post.

12.22.2006

2007 Predictions

Everybody doing it! Not wanting to be left in the cold, I will follow the herd and make predictions for 2007.

RoR will run flawlessly on a Java Application Server

The good people from JRuby are making incredible progress since they've been hired by Sun. We will soon be able to run RoR applications with no (or very little and trivial) modifications on Glassfish or other Web Container. Will that makes RoR application more scalable? I'm not sure. But it will increase RoR momentum in Java shops. When you talk about RoR to a java shop, the first question they have is "Will it run on Tomcat|WebLogic|WhebSphere|...?"

JRuby will take the top spot for scripting the Java platform

To the demise of Groovy, JRuby will take the spotlight. The main reason is the previous prediction. Once you can run RoR on a Java application server, nobody will need Grails. Grails is the only use of Groovy that create adoption.... Unless some other killer Groovy application, tool or framework is created.

RoR adoption continue

That's a fairly conservative prediction. RoR as a lot of momentum.

Java 6 adoption will start slowly in Q3

While Java 6 is out. It's adoption will grow slowly and will mainly be driven the scripting language support. Java 5 had many compelling reason to get adopted by many shops, but many many many application are still running on Java 1.4. Beside scripting support, there is nothing compelling enough in Java 6 to make it's adoption within the enterprise faster that Java 5.

Something will happen in Java build tool space

A lot of people are tired of Ant . Maven is cool, but lacks flexibility. Scripting language is getting more attention... We have Gant, Raven, JRake and many other existing or yet to be created build tool that use scripting language. By the end of the year, one of them will start getting a lot of traction. My best guess for now is Raven.

Java Specification Requests will become less and less relevant

The JCP is not working very well. It's too lengthy. Design by comity does not work well. Many JSR do not stand the sand of time. Today JSR mostly reflect some existing API with less feature (JPA vs Hibernate for example). They do not offer innovation, they just tend to seal mature innovative technology in the platform. New language features takes too long to traverse the JCP and with the open sourcing of Java, it will become easier for one group to add new feature to the language and to make a Java distribution of it's own. And with JSR like JSR-277 that create more turmoil than solve any problem, more and more people loose interest and faith in the process. Sun is not even interested in really supporting existing JSRs. We have a JSR for Groovy, but Sun hire the JRuby developers without giving any resource to Groovy. That's it! I made my prediction for 2007. This is probably my last post of the year, I will try to post a bit more often next year! In the mean time, have a Great Christmas and a really Happy New Year!

10.25.2006

added: Emmanuel's Development References search engine

I've just created a new search engine using Google Coop. You can start using it on by entering search terms on the search box on the right.

You may also add it to your browser's (Firefox 2.0 or IE 7) search engines.

This search engine is customized to search Java, Ruby, Rails, Hibernate and Spring Framework API and reference documentation. More API and reference documentation for things that are in my area of interest will be added in the future.

10.18.2006

Ant without the XML

Yet Another Build Framework was announced today on The Server Side. Gosling is much like Ant (according to the website, it's a fork of Ant) but without the XML. For a start, this is good news. Instead of using XML, you use Java to code your build script.

Do we really need another build framework? Sure writing build script in XML is not very convenient and has its limitations. But we have Maven2. Maven2 is still XML, but it is not build script that you write in XML, it's just your project configuration. Maven2 is the perfect implementation of DRY for your build script. After more than 10 years of Java existence, why would one still have to write in is build script the steps required to produce a JAR file?

Does this mean that Gosling has no future? No! I think it's very nice to have an alternative to Ant to create build script (for those who don't like Maven2 very much). I also think that this would be a nice framework to create build task for Maven2. Because you are using code to create your build script, you can use a debugger to debug them. In that respect, it's much better than Ant and Maven2. I imagine, it would also possible to write libraries of tasks that could be downloaded on the fly (using dependency management) to be able to actually not repeat yourself.

Right now, this framework requires Java6. This is not a very good idea to drive adoption, Java5 and even Java 1.5 should be supported.

But the feature I would want the most for this project would be to be able to write my build script in a scripting language. Be it Ruby (with the help of JRuby) and/or Groovy! That would be much better than XML :-)



9.22.2006

The simplest thing to do...

I have been living in the Java world for a long time now. In this world full of patterns, complicated API and well intentionend flexible frameworks, we do not always follow the simplest path to a solution.

I'm currently working on adding some functionnality to an application that we wrote for a client last year. This application written in Java using JSF/Facelets/Spring/Hibernate and running on Tomcat.

For the new functionnality, I wish to move information from page to page but I don't want them to stay in the session for long. I also don't want to explicitely have to remove explicitely these object from the session. Now I could use request scope attributes to do that, but then if I choose to do a redirect instead of a forward, I will loose the information. I could also go with a more complicated option of using Spring WebFlow (or something similar). But I don't want to another layer and more configuration files.

In the weeks before starting this new project, I wrote some application using Ruby on Rails. The philosophy behind this framework is very different than the philosophy behind most Java frameworks. Here the DRY (Don't Repeat Yourself) principle is king. This contrast a lot with the stack I'm using as I have to define information about my controller, pages, beans in multiple places.

One of the concept I found useful in Rails is the Flash. The Flash is a hash structure like the session but it retains objects up to the end of the next request. It's a bit like the request scope with the added benefit of surving redirects.

So I thought, why not implement this in Java. For my Java implementation, I choose not to implement the "now" operation that is present in Rails as I did not really needed it. I also use a filter to do the management of the Flash.

This simple solution allow me to pass objects from page to page without having to polute the session to much. It has the benefit of allowing request-like scope to survive redirects. The current implementation may not work well with Ajax requests (I use Ajax4JSF and I have yet to find a way to differenciate Ajax request from normal requests, so the objects will be purge when doing an Ajax request unless I explicitely retain them when processing the Ajax request).

So here is the code (the two classes must be in the same package). Note that you can customize the Filter mapping to suits your particular needs.

Flash.java
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Flash extends HashMap<String, Object> implements Serializable {
    private Map<String, Integer> time2live= new HashMap<String,    Integer>();
   
    @Override
    public Object put(String key, Object value) {
        time2live.put (key, 1);
        return super.put(key, value);
    }
   
    public Flash keep(String key) {
        if (containsKey(key)) {
            time2live.put(key, 1);
        }
        return this;
    }
   
    public Flash keep() {
        for (Map.Entry<String, Integer> entry : time2live.entrySet()) {
            entry.setValue(1);
        }
        return this;
    }
   
    public Flash discard(String key) {
        if (containsKey(key)) {
            time2live.put(key, 0);
        }
        return this;
    }
   
    public Flash discard() {
        for (Map.Entry<String, Integer> entry : time2live.entrySet()) {
            entry.setValue(0);
        }
        return this;
    }
   
    void manageFlash()  {
        for (Iterator<Map.Entry<String, Integer>> entries= time2live.entrySet().iterator(); entries.hasNext();) {
            Map.Entry<String, Integer> entry= entries.next();
            if (entry.getValue() == 0) {
                entries.remove();
                remove(entry.getKey ());
            } else {
                entry.setValue(entry.getValue()-1);
            }
        }
    }
}

FlashFilter.java
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest ;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @web.filter name="FlashFilter" display-name="Flash Filter"
 * @web.filter-mapping url-pattern="*.html"
*/
public class FlashFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest= (HttpServletRequest)request;
       
        Flash flash= (Flash) httpRequest.getSession(true).getAttribute("flash");
        if (flash == null) {
            flash= new Flash();
            httpRequest.getSession().setAttribute("flash", flash);
        }
        flash.manageFlash();
       
        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }
}


12.07.2005

Fixing iTunes 6 library with Ruby

Like many people, when I upgraded iTunes to V6, I had problem with my iTunes library. For some reason, in the upgrade process iTunes lost the location of many mp3 files in its library.

I was unable to use the fix proposed by Apple as I do not immediately found out about the problem. I added stuff to my library and would loose all me new playlists and ratings if I followed it. Also, I was not able to find a version of my library dated at the time of the upgrade.

I have something like 1200 songs in my library, more than 200 of them lost the location of the actual mp3 file. Clicking around to try to find them within iTunes would have take me days.... And bored me to death.

So I wanted to add all these files back to my library while keeping their rating (I did not care much for the last play time and play count).

I've started to play with Ruby a few weeks ago. I use it to test web application using Watir. I thought that fixing my iTunes library with a small Ruby script would be a fun thing to try.

So I did... I wrote a small Ruby script that would connect to iTunes using the Win32 OLE interface. The script is fairly simple, it check each tracks in the library and if it's location is an empty string, it try to find the music file (mp3 or m4a), add it back to the library and set it's rating to the same rating as the current track.

Note that I could not just set the Location property of the track as this property is read only using the iTunes OLE interface.

A few minutes later, all the music files that matched to a song name were added back to my library with the proper rating. I did have to get rid of the duplicates entries in my library. But at least iTunes allows one to easily show duplicate songs. It was just a matter of selecting songs with the (i) icon, right-clicking and pressing clear.

I also wrote another Ruby script that would scan my music folder and add music file that were not already present in my library. This was necessary as my first script missed some files. I lost my rating for these files but there was'nt that many of those.

So here are the Ruby script, customize them to your liking (like the music base folder) and use them to fix your own library. But do so at your OWN RISK. I do not garantee that they will work for you!

Script 1 :

require 'win32ole'

iTunes= WIN32OLE.new('iTunes.Application')

tracks= iTunes.LibraryPlaylist.Tracks

totalTracks= 0;
tracks.each {|t|
  totalTracks+= 1
  if t.Location == ''
    puts t.Name
   
    name= t.Name
    Dir.glob(File.join("D:\\My Music", "**", "*#{name}*.{mp3,m4a,MP3}")) {|l|
      puts "Adding #{l} to iTunes"
      status= iTunes.LibraryPlaylist.addFile(l)
      while (status.InProgress) do
        sleep(0.5)
      end
      status.Tracks.each {|track|
        track.rating= t.rating
      }
    }
  end
}

puts totalTracks

Script 2 :

require 'win32ole'

iTunes= WIN32OLE.new('iTunes.Application')

tracks= iTunes.LibraryPlaylist.Tracks

totalTracks= 0

Dir.glob(File.join("D:\\My Music", "**", "*.{mp3,m4a,MP3}")) {|l|
  found= false
  tracks.each {|t|
    if t.Location.rindex(File.basename(l)) then
      found= true
      break
    end
  }
  if (!found) then
    totalTracks+= 1
    puts "Adding #{l} to iTunes"
    status= iTunes.LibraryPlaylist.addFile(l)
    while (status.InProgress) do
      sleep(0.5)
    end
  end
}
puts totalTracks

Have fun!

AdSense Links