Archive

Posts Tagged ‘programming’

Writing your own JRuby extension. Part II: Creating your first class.

March 12th, 2010 Serabe No comments

More Mormon Matryoshki
What’s the point of coding a JRuby extension if you don’t create classes? Well, I cannot think of any case, but if you find one, please, let me know.

Do you remember Java’s classes hierarchy? If so, you’ll realize  that Java objects inherit from java.lang.Object by default but that is not actually what we need. But how can we tell JRuby that our object inherits from Object, the king of Ruby world? The answer is so simple: just extend RubyObject! (There is a RubyBasicObject too) Taken from Nokogiri::XML::Node:

Of course, you can extend any other class, as long as it is a “Ruby object”. For example, Nokogiri::XML::Document extends from Nokogiri::XML::Node, and we do not need to do anything special to reflect it, just extend XmlNode like XmlDocument does:

After talking a bit about hierarchy, let’s talk about Java constructors. At least two parameters are needed: a org.jruby.Ruby object and a org.jruby.RubyClass object. Being the importance of the former quite obvious, the reason for the latter may not be so clear. Let me show you some real world code: Nokogiri::XML::Node’s dup method. Take a look at the following test:

Both new and dup methods in subclass rely on Nokogiri::XML::Node’s. In here, you can see the this snippet of code:

The rb_obj_class method returns the class of an object, in this case, self. This way, the new node will be an instance of the same class as the original node. That’s the reason a RubyClass is needed in the constructor, in order to know which is the actual class being instantiated.

By the way, do not forget to call super with the Ruby and RubyClass objects.

Next step: creating methods.

Creative Commons License photo credit: quinn.anya

Writing your own JRuby extension. First problem.

January 11th, 2010 Serabe No comments

Denial
Maybe, when requiring your just created extension, you get a LoadError. If it is the first time you require it, it is quite likely that you have not followed JRuby requiring conventions. If you want to know how require works, you can find the best documentation ever about it in the comment before org.jruby.runtime.load.LoadService class.

Creative Commons License photo credit: cesarastudillo

Writing your own JRuby extension. Part I: BasicLibraryService.

January 8th, 2010 Serabe No comments

Note: not code in this post, but you can see the code in Github. Follow the links!

Writing a JRuby extension is very easy, but there are almost not post out there about it. As far as I know, there is only one, Ola’s. It is a really good tutorial indeed, but it lacks some details that might be not-that-easy to solve. Please, take some time to read it and, if some details are different, do follow Ola’s way.

Everything’s ready now, so let’s start talking about BasicLibraryService. If you take a look at Nokogiri4J sourcecode, in ext/java/nokogiri folder, you will see a NokogiriService.java file. NokogiriService implements BasicLibraryService. This interface consists only of the method basicLoad which receives a Ruby object.

We will use this method to define classes and methods in the Ruby world. For defining a module, defineModule method is used with the name of the module. After that, modules and classes under that module can be defined easily by using the methods defineModuleUnder, which takes the name as parameter, and defineClassUnder, which takes the name and few parameters more. Let’s dive into it.

defineClassUnder needs three arguments. The first one is the class’ name. The second, is the parent class. If you have defined it previously, just passed it,  otherwise use RubyObject by calling the method getObject on the Ruby instance. The third parameter is an ObjectAllocator. ObjectAllocators returns intances of the classes in Java world. When instantiating Nokogiri::XML::Comment in Ruby world, JRuby will ask the ObjectAllocator for an instance of the Java class. It passes a Ruby object and the RubyClass being instantiated to the allocate method in the ObjectAllocator (more on RubyClass in following posts).

Finally, we will need to define some methods. Easiest way is by using the defineAnnotatedMethods. It takes a Java class as parameter. For knowing what this method does, you need to know a bit more about @JRubyMethod annotation (more on it in following post, have you realized the “Part I” in the title?). As you define methods, you may need to undefine some in a subclass. So easy! Use the undefineMethod method, which takes the name of the method as parameter (surprisingly, it undefines a method by redefining it!).

Next time, Implementing your first class.

If you are (un)happy with Ruby 1.8.7

February 12th, 2009 Serabe No comments

There are two interesting topics in the Ruby Forum being discussed right now. Both opened by George Brown (the guy behind Prawn). They are:

I’ve read every single message because backwards compatibility in Ruby 1.8.7 is something that I do not fully understand. It all started with this comment in Jaime’s blog. There, Jaime wondered if Ubuntu did the right thing by updating Ruby to 1.8.7, even if that version breaks rails (in fact, it did). Well, in this case, my humble opinion was yes, Ubuntu did well by updating Ruby. But now, let’s consider other things.

So far, I’ve seen two kind of complains against Ruby 1.8.7:

  • Coding working in 1.8.6 that doesn’t work in 1.8.7. I’ve been talking James Coglan about it, and the one of the errors was that his code relied on the order of the keys in a hash. But, there are other he hasn’t been able to fix, and is something regarding regular expression. I am unhappy with this kind of “new features”.
  • Other people is complaining about working code in 1.8.7 that does not work in 1.8.6. I really understand them, because they program really cool gems and they have to test if they have used not-valid-1.8.6 code. I wouldn’t care too much about but we must keep in mind that 1.8.7 is a minor release.

Finally, I just want to say that, as many people has pointed out before me, it would be better to migrate to 1.9.1. Common! It has been already released! Anyway, that’s not the point of the discussion. It is all about a minor release with too many changes (I’m not talking about bugfixes). Do I like the new things? Yes, I do (except some that I cannot really understand). Am I happy with Ruby 1.8.7? No, I’m not because it is suppose to be a minor version release and it is making too much noise.

Problem 3

October 12th, 2008 Serabe No comments

Wording: (Original) The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?

Solution:
First the code:

RUBY:
  1. include Math
  2. def prime_factors(num, factor=2)
  3.   return []  if num <= 1
  4.   next_pf = (factor..(sqrt(num).ceil)).find(lambda {num}){ |x| num%x == 0 }
  5.   return [next_pf] + prime_factors(num/next_pf, next_pf)
  6. end
  7.  
  8. puts prime_factors(600851475143).max

The code is a direct port from the one in PyEuler. It is based mainly in the idea that the first factor of a number is always prime.

Line 3 breaks recursion and line 4 works out the next prime factor (actually, it finds the smallest factor). For doing this, it uses find method. If no element match the criteria, then it returns the number (that is what the lambda block is for).

Finally, line 5 merges the results and line 8 print the result.

This time just one code is showed.

Programmers Jokes.

August 29th, 2008 Serabe No comments

In C we had to code our own bugs. In C++ we can inherit them.

C gives you enough rope to hang yourself. C++ also gives you the tree object to tie it to.

With C you can shoot yourself in the leg. With C++ you can reuse the bullet.

A computer without COBOL and Fortran is like a piece of chocolate cake without ketchup and mustard.

Why all Pascal programmers ask to live in Atlantis?
Because it is below C level.

Programmers Jokes.

Hug a developer today.

August 28th, 2008 Serabe No comments

Hug a developer today. They are in pain. At least, I work for a Open Source project, so I have no boss... but me.

Anyway, you can hug me if you want :-) .

Taken from.

RMagick4J 0.3.6

August 16th, 2008 Serabe No comments

I am glad to announce a new version of rmagick4j.

RMagick4J aims to implement the ImageMagick funcionality and the C
portions of RMagick for make it works in JRuby.

Current stable version: 0.3.6
Project URL: http://code.google.com/p/rmagick4j/
Installation: gem install rmagick4j

Google Summer of Code project should be thanked for making this new
release possible.

In release 0.3.6 you can find the next improvements:

  • More Draw primitives (clip-path [creatin a clip-path and using a
    clip-path], fill-rule, rotate, scale [reimplemented], skewX, slewY,
    stroke-linecap, stroke-linejoin, stroke-miterlimit, translate).
  • Solve a bug with transparent stroke and line primitive.
  • Added the following Draw instance methods:
    • annotate
    • get_multiline_type_metrics
  • Solved a bug that caused the background become black while resizing
    images with alpha channel.

Please try out your applications with rmagick4j and help us provide
feedback. It is our goal to make a fully-compatible implementation of
RMagick4j in JRuby.

RMagick: Dibujar con patrones

July 22nd, 2008 Serabe No comments

Una interesante cualidad de la clase Draw de RMagick es la posibilidad de definir patrones a través del método pattern.

En primer lugar, lo básico:

RUBY:
  1. require 'rubygems'
  2. require 'RMagick'
  3.  
  4. include Magick

Ahora definamos el patrón. Para ello, necesitamos cinco parámetros, el nombre, dos números que recomiendo ponerlos a cero (después de unas cuantas pruebas, no he notado diferencias notables) y después las dimensiones del patrón.

RUBY:
  1. draw = Draw.new
  2.  
  3. draw.pattern('circles', 0, 0, 10, 10) do
  4.   draw.stroke 'none'
  5.   draw.fill 'red'
  6.   draw.rectangle 0, 0, 10, 10
  7.   draw.stroke 'LightGreen'
  8.   draw.fill 'blue'
  9.   draw.circle 5, 5, 5, 0
  10. end

Ya, por último, dibujamos un cuadrado y lo plasmamos en una imagen de 300x300.

RUBY:
  1. draw.stroke 'circles'
  2. draw.stroke_width 25
  3.  
  4. draw.fill 'none'
  5.  
  6. draw.polygon 150,0, 300,150, 150,300, 0,150
  7.  
  8. img = Image.new 300, 300
  9.  
  10. draw.draw img
  11.  
  12. img.write 'pattern.jpg'

Obteniéndose el siguiente resultado:

Dibujo con patrón como brocha

Dibujo con patrón como brocha

Ay, Serabe, que no haces nada ni tan siquiera regular.

May 18th, 2008 Serabe 3 comments

Hoy me he tirado unas cuatro horas para encontrar un bug, uno de estos puñeteros bichos que te atrapan y te dejan cosas como estas:
The Picture of the day
Para que os hagáis una idea, tenía que ser esto:

Como se puede apreciar, son sensiblemente diferentes. Así que cuatro horas de mi vida han transformado lo primero, en lo segundo.

El problema venía en que, tal y como Tom (mi mentor del GSoC) propuso, se ha cambiado la clase PixelPacket de forma que ahora trabaja con enteros. El problema, mejor no os lo cuento que es más aburrido que lo anterior.

En fin, que hoy me voy a la cama con un ego más grande que el de Enrique Dans.

Improve the web with Nofollow Reciprocity.