Sunday, September 24, 2006

Perl: File handle as function argument

Recently I was writing one function in Perl. And I come across one little problem - I did not know how to pass and file handler to a function. Nothing big, but it gave me a little of googling to find the answer for this.
So, let me just give a solution to this problem, without any further explenation.

#!/usr/bin/perl
use strict;

open(FH,"> some_file.txt");
print FH "Write first line to the file";

writeToFile(*FH);

sub writeToFile {
my $FH = shift;
print $FH "Write second line to the file";
}

Hence, one must remember that when we past a file handler to a function in Perl, we must do it using '*', no other way that I know of works.

Ruby, is it worth my interest?

Recently, I read about new scripting language from Japan - Ruby. I already know quite good Perl, so I decided to read a little more about this, because what I had read, expressed very good opinion about this new language.

Ruby, as its homepage says, is: "the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, extensible, and portable ... and free of charge".

On the grounds of above, I decided to give it a try.

Installation

I was surprised to find out that my Mac X Tiger has embedded Ruby interpreter. So users using newest Mac's don't have problems with installation. Despite this, i decided to install it on my Ubuntu Breeze, by running sudo apt-get install ruby. As a result, Ruby was installed on my Linux.

My first script

To get an idea about this programming language, I decided to write a little program, that reads two text files containing mainly numerical data, organized into tables (tabulator as separator between columns). Below is an example of file's content:


As can be seen from the table above, it is typical text file with data. I used two such files, but with different numerical data. I wanted to write some script that takes those to files, performs some mathematical operation on numerical data, and gives summary of calculation.

In this moment I'm not going to describe or explain further details attributed to this script, or give any example code. Just want to share my opinion about my first impression of Ruby.

First steps

I must say, that starting to learn Ruby, was quit easy. This is mainly because of book-like tutorials available at Ruby's homepage. I hadn't have any major difficulties in writing my script. However, there was one thing which caused a little of confusion at the start - iterators like in line (2):

myarray = [1,2,3,4] # (1) create array of name
myarray.each { |i| puts i} # (2) for each element in myarray do 'puts i'-print i

But, after a while, you can get used to them, and what's more important, see how useful they are.

There are many more other inventions in Ruby, which I will be describing as time goes.

Conclusion

In conclusion, I must say my program was written relatively fast. I didn't have any bigger problems with it. However, there was huge problem with making intersection of two arrays of objects, but my own solution to this obstacle, I will describe later. Despite this I must definitively say that I will continue to use Ruby, because it is very clean and easy language.

Mysql, mysqld.sock missing

Lately I find my self in trouble with running mysqld 4 on Ubuntu 5.10. The problem was with missing mysqld.sock. While starting mysql I saw:

/usr/bin/mysqladmin: connect to server at 'localhost' failed error: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock (2)' Check that mysql is running and that the socket: //var/run/mysqld/mysqld.sock' exists !

Normally mysqld.sock is created by running mysqld command. Unfortunately, this command gave:

/usr/sbin/mysqld: Cant't open file: 'host:MYI'. (errno: 142) Fatal error: Can't open privilege tables: File = '/usr/share/mysql/charsets/?.conf' not found (Errcode: 2)

First I tried mysqld --default-character-set=latin1 but it did not help. So I finaly executed

myisamchk -dvv host.MYI

and I saw

myisamchk: Character set '#'83' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index' file myisamchk: error: 142 when opening MyISAM-table 'host.MYI'

The solution was to add to file /usr/share/mysql/charsets/Index only one line:

cp1251 83

Sunday, September 10, 2006

Perl: Creating empty arrays and hashes

Using arrays and hashes in Perl is essential. Nevertheless Perl way of handling those data types is more difficult; by comparison with, for example Ruby or Python. Now I am not going to focus on all aspects of arrays and hashes in Perl, because this topic is just to big for one post. Today, I will describe funny problem that my co-worker had, or rather his little bug in his program.

The problem was with deleting or emptying and array or hash.
For example, let assume that we have one array @a, and one hash %h:

my @a = ( 2, 3, 4);
my %h = ('me'=>2, 'you'=>3, 'he',=>'4');

print 'Size of @a: ', scalar @a; #gives 3
print 'Size of %h: ', scalar keys %h; #gives 3


Now, we want to delete its content. What my friend did, was:


@a=[]; #WRONG: should be @a=();
%h={}; #WRONG: should be %h=();

print 'Size of @a: ', scalar @a; #gives 1 !!!
print 'Size of %h: ', scalar keys %h; #gives 1 !!!


This little mistake cost him a lot of hours of looking for bug in his code. What he did, he created anonymous empty array [] and anonymous empty hash {} and assign them as first element in $a[0] and as first key in %b.

Hence, the correct code to empty an array or a hash is:


@a=();
%h=();

print 'Size of @a: ', scalar @a; #gives 0 !!!
print 'Size of %h: ', scalar keys %h; #gives 0 !!!