Friday 30 November 2012

Oracle sqldeveloper, openjdk, .xsession-errors and no disk space

The file ~/.xsession-errors is eating all of the file system!
I had this problem happen to me before when I was using Ubuntu, at the time I didn't figure out what the problem was, but I solved it with ln -s /dev/null .xsessions-errors and called it quits. Today however, it happened to me on my Fedora system. However this time I figured it out.
Earlier today I had installed Oracle's sqldeveloper, I tried to lunch it a couple times from the GUI, when that failed I went to the console and typed "sqldeveloper", I was graced with the following message:


Error: /bin/java not found
Type the full pathname of a J2SE installation (or Ctrl-C to quit), the path will be stored in ~/.sqldeveloper/jdk
So I gave it my JAVA_HOME, set some config file so it would ignore the fact that I was using open-jdk and voilá.

Seven hours later I'm getting no disk space errors, wtf? 
Scan tells me that my music folder is the biggest file system hog.... sure I can understand that, but it's not like it's growing right now...
Open up the console, ll -ash and bam! .xsession-erros is 11G! 
I tail the file and the oracle's lovely error message and input request is being written on that file at monitor-flickering speed. 
The command ps -aux reveled to me that I had 3 instances of sqldeveloper open since morning, killed those and the file stopped being written on. 
Now just removed it and all is well.

TL;DR: Bad Oracle! BAD!

Wednesday 7 November 2012

Complete Guide to install Ruby 1.9.3 on CentOS

UPDATE: These instructions also work on Fedora 16 ( and possibly bellow; on 17+ you should have Ruby 1.9.3 on yum repos).
There are some nice guides out there, like this one, explaining how to do this, but they don't tell the complete story, especially if you're on a clean CentOS install - which is the only explanation I can come up with for the fact that other guides didn't have the same problems I had.


EDIT 11/12/2013: The version listed on the instructions bellow is a bit dated, since this post is now 13 months old, check https://www.ruby-lang.org/en/downloads/ for the latest ruby 1.9.3 patch and replace the patch number (p194) with the latest one on step 9 (wget [...] ruby-19.3-p194.tar.gz).

Steps I ended up following:

#preparing packages
$ sudo yum groupinstall 'Development Tools'
$ sudo yum install -y httpd-devel openssl-devel zlib-devel gcc gcc-c++ curl-devel expat-devel gettext-devel patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel make bzip2 zlib1g mysql-server

#compaling libyaml
$ wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
$ tar xzvf yaml-0.1.4.tar.gz
$ cd yaml-0.1.4
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
#compiling ruby 1.9.3
$ wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz
$ tar xvzf ruby-1.9.3-p194.tar.gz
$ cd ruby-1.9.3-p194
$ ./configure
$ make
$ sudo make install
#rubygems
$ wget http://rubyforge.org/frs/download.php/76073/rubygems-1.8.24.tgz
$ tar xvzf rubygems-1.8.24.tgz
$ cd rubygems-1.8.24
$ sudo /usr/local/bin/ruby setup.rb


During the preparation stages a few packages may say they already installed, don't worry.
I'm not sure still if it will work with everything (like rails if that's your thing) but at least 
(Update I've installed both Rails and Sinatra without any problems on top of this setup)
I have been able to install some gems now which by other guides I followed fell short of.

Monday 5 November 2012

Time Helper 2.0.0 released

Funny how time-helper is older than this blog yet not a single post or page about it here.

I've considered this a new major version because there's no guarantee of compatibility with previous versions, in a couple features.

About version 2.0.0

I've changed the =~, the old way was just stupid (no one else to blame but me here), the new version just compares two Time objects and see if they are within an acceptable distance from each other in seconds, defaults to 300 (5 minutes).
So where you'd have a symbol as first argument you now have a Fixnum. Also added a sanity check for the second argument.

Completely removed the #parse integration in #strtotime, this means that if you were using #strtotime as both it won't work, as such, it reduces the memory footprint of this gem (by not requiring stdlib time)  for those who don't want .parse - which is most of the people that I've made this gem for (including myself).

And yes, this gem still doesn't care about American date format (mm/dd/yyyy), because it's silly.

I've already found a couple issues that need to be fixed:
  • Documentation for =~ doesn't completely reflex the changes.
  • Time.valid_datetime? returns true for more than intended inputs.

How to make TM, C and R symbols on Keyboard - Linux ™,©, ®

Silly short post, I was playing with the keyboard and finally figured this out, quite useful, so I'm making a post for:
a) I can refer to later.
b) Other people may find later.

I only tested this with Ubuntu, so there

These 3 symbols work in combinations of Alt Gr + Shift + [KEY], I'll list the key:

  • ™ - 8
  • © - c
  • ® - r

Tuesday 23 October 2012

Ruby: hiding method from an instance

This one is simple, for some reason I needed to hide a method from an instance so people would use my wrapper instead of the method directly - I have good reasons, but to achieve this we can, again, resort to instance_eval:

irb(main):001:0>  class A
irb(main):002:1>  def a
irb(main):003:2>  p 'hello world'
irb(main):004:2>  end
irb(main):005:1>  end
=> nil
irb(main):006:0> 
irb(main):007:0*  a = A.new
=> #<A:0x0000001fbee140>
irb(main):008:0>  a.instance_eval do 
irb(main):009:1*  alias :b :a
irb(main):010:1> def a
irb(main):011:2> p 'you should not use this method'
irb(main):012:2> end
irb(main):013:1> end
=> nil
irb(main):014:0> a.a
"you should not use this method"
=> "you should not use this method"
irb(main):015:0> a.b
"hello world"
=> "hello world"

Monday 1 October 2012

Codebits 2012 Talk preview

I decided I'd not be myself if I did not add some humour and memes to the presentation. So here's the first one I've come up with:


Monday 24 September 2012

Clearing excel formula cache when using jruby-poi - making Formulas work right

Last week I've been working with jruby-poi to make an script that would automatically update an MS Excel file.
The part that cost me the most time, believe it or not, was formula updating, you see, I would add rows that should change the value of pre-set  formulae, but the results would not update on Excel until you clicked on the formula.
After diving in the nearly nonexistent documentation of the gem (they give you base-usage on git, some test case you can check out also on git, everything else is default generated rdocs without a single improvement) I've came up with the following work around:


       %w[jobs defects].each do |sheet_name|
            sheet    = self.workbook.worksheets[ sheet_name ]
            rows     = sheet.rows
            from, to = 2, 70
            rows.each_with_index do |row, i|
                next if i <= from
                #order is important!
                %w[L K D E F N O P Q U V X Y Z W AA AB AC AD AE AF AG AH AI AJ].each do |letter|
                    column = letter.to_number - 1
                    puts sprintf( 'updating formula on C: %s row %d', letter, i )
                    self.workbook.on_formula_update rows[ i ][ column ]
                end
                break if i >= to
            end
end


I hope it helps anyone, also I've opened an issue on their git, let's see how they respond.

Thursday 20 September 2012

Codebits Talk Approved

After being accepted earlier to Codebits 2012, my talk was also accepted.
Now I gotta pretend I'm an expert in some stuff.


Wednesday 19 September 2012

Turning letters into numbers in Ruby (Excel style)

Today I was writing some code to update an Excel file with more recent data from various sources. I was using JRuby with jruby-poi, it provides a nice API and so far it's the only gem I found that can open and edit an xlsx file without breaking it.

I had an interface problem however, I was trying to provide the people that will use my code an easy interface, so I needed them to be able to pass me [excel's] columns as letters (A, B ,C...), but for editing with poi the interface is the object Rows, an Enumerable with numbered indexes like an Array, that is, I can't do rows['A'][1], I must do rows[0][0].

Googled around for a few ideas and I came up with this (it works up to column AZ as far as I know)

class String
    def to_number
        number = self.tr("A-Z", "1-9a-q").to_i(27)
        number -= 1 if number > 27
        return number
    end
end


It works fine with strings that are just an capital letter, I didn't do a sanity check because you might wanted convert a bunch of letters in the same string, also because your column might be something like 'AA' or 'AB'. If you were looking for the simple answer you can stop reading here.

I'm gonna math-nerdout here a bit to explain what is happening:
the method "tr" here will replace everything from "A" to "I" with the numbers from 1 to 9, everything else will be replaced with the letters from "a" to "q" which are the numbers and letters used in the base 27 numeric representation.

For those of you unfamiliar with numeric which aren't base 10, they are represented as such:
0 to 9 stays the same, but everything after that are letters from English alphabet.

So 10 in base 27 is 'a', 26 is 'q' (the last letter used by base 27) and 27 is '10'.

(Don't ask me how are numbers represented in any base greater than 36 (where 35 is 'z'), Ruby won't accept any greater base anyway.)

The argument 27 in the "to_i" call is to tell ruby that the string is a number in base 27 for when it does the conversion to Fixnum (you can also "to_s 27 "if you want to convert a number to base 27 ).

Let's say your string was 'AA', the tr method will turn it into '11', this is not "eleven", in base 27 this is 28*. But the result we wanted is 27, not 28 (AA is column number 27), thus the "-1 if number > 27".

I could explore this solution to come up with some better math to make sure this method worked correctly even if you're looking for column 'ZZZZZ', but I don't need it, as this was a very small problem from the big problem I was facing today.


*Trying to explain this in layman's terms (since I myself am a layman) 
Normally we represent numbers in base 10, this means that when we get to the number "ten" it kinda loops the representation and goes back to zero preceded by a 1, this one indicates how many "full loops" we've done to the base so we represent the number ten like so: "10".

However, if we increase the base , we need more symbols, so at base 20 when we reach "ten" we can't represent as "10" (that would be twenty) because we haven't looped it yet, so we just borrow letters till we have enough symbols to represent all numbers in one loop of the base.

In the case of base 20,  we represent one as "1"; nine as "9", ten as "a", nineteen as "j", twenty as "10".

Tuesday 18 September 2012

Uploading attachments to Jira using Jira4r

Today I found myself needing to make a ruby script that would update a file and upload it to an issue as an attachment in Jira.
I found the SOAP API method to do this in Jira's documentation, but I didn't find a suitable mapping in the Jira4r docs.
I found this comment on the Jira4r page, the only  reference to the API's addBase64EncodedAttachmentsToIssue method. Also found some forum posts of people with the same issue and that comment was the only found solution.
So if you need to upload stuff to Jira, follow the instructions in that comment, you'll find the file to edit at "[GEM_PATH]/gems/jira4r-0.3.0/lib/jira4r/v2/jira_soap_service_driver.rb"
The end result I got in my file for it to work was this, worked for my task.

The usage is quite simple, the test example on the page linked shows well how to use it, I'm just going to paste here to keep it "in record".
The only difference between what I did and what's on the example is that I used the base64 standard lib for encoding while he uses Array#pack('m') which results on the same thing.


#!/usr/bin/env ruby
$LOAD_PATH << './lib'
gem('soap4r')
gem('jira4r')
require 'jira4r'
require 'base64'
require 'cgi'
jiraBaseUrl      = "http://localhost:8080"
jiraUsername     = "automated-user"
jiraPassword     = "Thbmahws,"
escapedPassword  = CGI::escape(jiraPassword)
jira = Jira4R::JiraTool.new(2, jiraBaseUrl)
jira.login(jiraUsername, jiraPassword)
newFilepath = "H:\\edisc\\Tst\\Printed\\Test.eml"
fileName = newFilepath.split('\').last
issue = Jira4R::V2::RemoteIssue.new
issue.project = "ED"
issue.type = "1"
issue.summary = "This is a test"
issue.description = newFilepath
returnedIssue = jira.createIssue(issue)

filedata = File.open(newFilename, "rb") { |f| f.read }
attachmentData = filedata.pack("m")
jira.addBase64EncodedAttachmentsToIssue(returnedIssue.key.to_s, fileName, attachmentData)

Tuesday 11 September 2012

Codebits 2012


The most recent batch of acceptance to Sapo Codebits 2012 has been released, gladly I'm in that batch; unless something bad happens I'll be in Lisbon in November.
Now all they need to do is approve my talk...

Sunday 9 September 2012

Terminal Keyboard shortcut on Fedora 17

Recently I've installed Fedora 17 on a machine to do some learning Devel, easy enough.
Small problem though, what's the keyboard shortcut for opening the terminal window?
Well, there's isn't, because they thought it was fun to remove it since you can add it yourself you lazy bum, god forbid a user friendly Linux distribution that's not  Ubuntu.
Anyway, I looked around the keyboard settings and found where I can add the shortcut, but I had a hard time figuring out how to fill it for my intended purpose. Amazingly Google was no help on this.
So this is how you do it:
Settings -> Keyboard -> Shortcuts -> Custom Shortcuts -> +
On name just put whatever you want, on command type "gnome-terminal".
Here's what it should look like.


Edit: If you're using KDE you should type "konsole". To get there, go to System Settings -> Custom Shortcuts; click on the Edit -> New -> Global Shortcut -> URL/Command.
Also, to take screenshots on KDE you need KSnapShot.



Wednesday 5 September 2012

Ruby - Spying on instance variables

This week I've been working on some code to be executed on cucumber's hooks, due to the lack of useful (or easy to read) documentation I found myself using a debugger to find out what info I could get from the object passed to the "After" block.
Deconstructing the object allowed me to see it had some instance variables with info I needed, but I could not retrieve it in any way, what a bummer, "it's right there!" I thought, if the debugger can get it so can I.
Poking the object a little I found "instance_variable_get" method (which I hadn't used before nor ever paid attention to it), since there's no real private variables in Ruby, you can get any instance variable despite if there's a method for it or not.
Translating this new acquired knowledge into simple examples:


Simple instance variable spying


irb(main):001:0> class A irb(main):002:1> def initialize var irb(main):003:2> @var = var irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> a = A.new 20 => #<A:0x56ee20fe @var=20> irb(main):007:0> a.var NoMethodError: undefined method `var' for #<A:0x56ee20fe @var=20> [...] irb(main):008:0> irb(main):009:0* irb(main):010:0* irb(main):011:0* var.instance_variable_get(:@var)
=> 20

This could have easily been avoided using "attr :var" on class declaration, and it's the result of bad encapsulation.
If class A is yours, then go change it so you can easily access vars you need, if it's not (comes from a gem, maybe) you can still change it, because ruby classes are always open (which is awesome), so just add "class A; attr :var;end" before instancing it and you're good to go.


Now, when you don't have control over the class nor when it's instantiated (like on cucumber's hooks) you can still use what's described above, but have the option of using instance eval to define a new method to access the variable you want, although I hear it's slower I didn't bother with benchmarks for this case.



Spying with instance_eval

irb(main):001:0> class A irb(main):002:1> def initialize var irb(main):003:2> @var = var irb(main):004:2> end irb(main):005:1> end => nil irb(main):006:0> a = A.new 20 => #<A:0x63fb050c @var=20> irb(main):007:0> a.instance_eval do @var; end => 20 irb(main):008:0> #or, if you need to do it often.... irb(main):009:0* a.instance_eval do def var; @var;end; end => nil irb(main):010:0> a.var => 20

Instance eval evaluates your block in the context of the instance, so you can run code on it like if it were on the inside, you even have access to "self".