tag:blogger.com,1999:blog-207519552024-03-08T13:03:23.942+00:00I'm Thinking With Sand Here!Oh look another blogAndy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-20751955.post-1852681452745482002011-11-14T14:43:00.004+00:002011-11-14T15:02:26.791+00:00A Quicky Queue<a href="http://q4m.github.com/">Q4m</a> is a lovely looking package which brings queue semantics to MySQL rather than having to use another server (say RabbitQM) for your queues. However being a good open source project installation is a challenge. I'm not one to back away from a challenge though. So this is how I managed to install Q4m on my Mac. First some points of interest<div><br /></div><div><ul><li>Don't install it on your Mac. Create a virtual Linux box using VirtualBox</li><li>Install a decent distro on there like Debian (I'm assuming Debian 6; Squeeze)</li><li>Make sure MySQL 5.1 is installed</li></ul><div>Assuming you've done that you will want to install the following packages</div></div><div><br /></div><div><span class="Apple-style-span" >apt-get install mysql-server-5.1 libmysqld-dev libssl-dev g++ libmysqlclient-dev gcc4.1 libdata-compare-perl liblist-moreutils-perl</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span">You will be asked for the root user password here. Keep it blank for the moment if you are using this guide as a way of evaluating q4m. If not then please set it with sensible password.</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span">Then it's off to get the MySQL source (I've used 5.1.49 here so change according the version of MySQL you had installed) and q4m (0.9.5). Then we'll un-tar the archives</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span" >cd $HOME</span></div><div><span class="Apple-style-span" >wget http://downloads.mysql.com/archives/mysql-5.1/mysql-5.1.49.tar.gz</span></div><div><span class="Apple-style-span" >wget http://q4m.kazuhooku.com/dist/q4m-0.9.5.tar.gz</span></div><div><span class="Apple-style-span" ><br /></span></div><div><span class="Apple-style-span" >tar zxvf mysql-5.1.49.tar.gz</span></div><div><span class="Apple-style-span" >tar zxvf q4m-0.9.5-tar.gz</span></div><div><span class="Apple-style-span" ><br /></span></div><div><span class="Apple-style-span" >cd q4m-0.9.5</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span">Once you're in this situation you are so nearly there :). You'll need to configure and then make like so</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span">./configure --with-mysql="$HOME/mysql-5.1.49" --prefix="</span><span class="Apple-style-span">$HOME/mysql-5.1.49" CPPFLAGS="-I/usr/include/mysql"</span></span></div><div><span class="Apple-style-span" ><br /></span></div><div><span class="Apple-style-span" >make</span></div><div><span class="Apple-style-span" style="font-family: 'courier new'; "><br /></span></div><div><span class="Apple-style-span">Assuming everything worked you will want to install the plugin to MySQL, run some scripts and then some tests. Doing this as root will make things work.</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span" >su</span></div><div><span class="Apple-style-span" >cp src/.libs/libqueue_engine.so /usr/lib/plugin/.</span></div><div><span class="Apple-style-span" >cp support-files/q4m-forward /usr/bin/.</span></div><div><span class="Apple-style-span" >mysql --user=root < support_files/install.sql</span></div><div><span class="Apple-style-span" >services mysql restart</span></div><div><span class="Apple-style-span" ><br /></span></div><div><span class="Apple-style-span" >DBI='dbi:mysql:database=test;host=127.0.0.1;port=3306' DBI_USER='root' DBI_PASSWORD='' ./run_tests.pl</span></div><div><span class="Apple-style-span"><br /></span></div><div><span class="Apple-style-span">Assuming everything is good you should see a lot of messages flying up the screen and a 100% pass rate. Congratulations on install q4m. Go have a coffee; you deserve it.</span></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-72952934261807201462011-03-01T18:32:00.009+00:002011-03-01T19:49:48.008+00:00Red Deadlock Redemption - MySQL Edition<span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">Howdy there. It has been over a year since I last put finger to keyboard and brought to you my tales of woe. Well here comes another one but this is about MySQL and deadlocks which are fast becoming my nemesis. MySQL seems to deadlock at the slightest of things. Too many processes, high contention tables, flies farting in Greenland; all seem to be a cause. </span></span><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">My latest deadlock problem was from trying to emulate Oracle sequences in MySQL.Sequences are most commonly used to emulate MySQL's auto-incrementing key except they have the advantage that they are not linked to a single table. They can also increment at a defined step increase and are atomic. The work I have been doing required this feature; the ability to atomically reserve a range of identifiers. So a table structure was defined (auto increment identifier, name of the sequence and the last assigned value) & the code was written but this left one very big problem. How do you seed the table? A naive approach was formulated</span></span></div><div><ol><li><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">Select for update the sequence in question</span></span></li><li><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">If it existed then update the row with the new value</span></span></li><li><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">If not then insert a seed row</span></span></li></ol><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">All well & good until a user reported back saying this procedure was deadlocking. How on Earth? I checked the row existed, if it did not then I inserted the data. All of this was carried out in one transaction so what was going wrong. You can find the condensed version of the logic from </span></span><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><a href="https://gist.github.com/849606">Gist</a> which also causes a deadlock.</span></span></div></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">Well +1 for being able to replicate the issue; it always helps. So why do we get this failure? Well it is all because of InnoDB locking model and this </span></span><a href="http://dev.mysql.com/doc/refman/5.1/en/innodb-next-key-locking.html"><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">little comment</span></span></a><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"> nestled in the depths of MySQL's documentation (thank you Tim Starling). </span></span></div><div><blockquote></blockquote><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><span class="Apple-style-span" style=" color: rgb(85, 85, 85); line-height: 21px; "></span></span></span></div><blockquote><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">Note that if you use SELECT FOR UPDATE to perform a uniqueness check before an insert, you will get a deadlock for every race condition unless you enable the innodb_locks_unsafe_for_binlog option. A deadlock-free method to check uniqueness is to blindly insert a row into a table with a unique index using INSERT IGNORE, then to check the affected row count.</span></span></span></div><div></div></blockquote><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">What what what?!? So what does this locking disabling do? Well it turns off next-key locking which combines index locking with gap locking in an attempt to avoid phantom reads (rows which appear in a table when you should have locked them normally caused by inserting new rows). So in the example process 1 and 2 locked the sequence table for rows which did not exist and to make sure no new rows appear. This stops both processes from inserting into the table so one has to fail.</span></span></span></div><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></div><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">Thankfully there are three options to resolve this. The first is to perform an insert ignore into the table before selecting for update. This will block the other process and the code cannot deadlock. The second way is to pre-populate the table with rows which we can then select for update. Number three is to retry the transaction & hope the deadlock does not re-appear.</span></span></span></div><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></div><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;">All are valid but option two is my preferred solution since it cuts out have to perform an insert I know will fail every-time I want a new identifier range. If the schema & data was a bit more dynamic then option one would be the best solution. Option 3 has the feeling of being a band-aid but I concede sometimes thats all you can do.</span></span></span></div><div><span class="Apple-style-span" style="line-height: 21px; "><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-family:arial;"><br /></span></span></span></div><div><span class="Apple-style-span" style="font-family:arial;"><span class="Apple-style-span" style="line-height: 21px; font-size: medium;">Anyway one deadlock down. Another to go but that will have to wait for another time</span></span></div><div><span class="Apple-style-span" style="font-size:medium;"></span></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-35489384051678109982010-01-27T12:23:00.003+00:002010-01-27T12:33:47.196+00:00Try::Tiny - 'Lightweight' try{} catch{} finally{}As a lot of people will know error handling in Perl normally amounts to<br /><br /><span class="Apple-style-span" style="font-family:'courier new';">my $val = eval { do_something_evil()};<br />die "Something evil happened: $@" if $@;</span><div><br /></div><div>Not too much of a problem here except this (in some very odd cases) will not correctly trap the error and it means writing cleanup code can be hard (whilst trying not to clobber the value of <span class="Apple-style-span" style="font-family:'courier new';">$@</span> at the same time). This is not an easy thing to do so enter <a href="search.cpan.org/dist/Try-Tiny">Try::Tiny</a> which is a fantastic module giving you full try catch & finally support in Perl. Meaning the above code looks more like</div><div><br /></div><div><span class="Apple-style-span" style="font-family:'courier new';">my $val = try {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> do_something_evil();</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">catch {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> die "Something evil happened: $_";</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">};</span></div><div><br /></div><div>Since I am a Java programmer first this syntax looks more natural to me. What is really impressive though is that finally support has now been added allowing us to do:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-family:'courier new';">my $val = try {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> do_something_evil();</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">catch {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> die "Something evil happened: $_";</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">finally {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> warn 'But first maybe some cleanup';</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">};</span></div><div><br /></div><div>This is a perfect tool for those situations where local just does not cut it (say resetting a value in an object no matter what happens to the code).</div><div><br /></div><div>Anyway next time you want to do error handling in Perl have a look at Try::Tiny; you won't regret it (and if you're wondering why I'm recommending this have a look at Try::Tiny's commit history on <a href="http://github.com/nothingmuch/try-tiny/">github</a> & you may see why).</div></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-41393719367529093802010-01-14T21:42:00.003+00:002010-01-14T21:55:34.368+00:00TAP That!TAP (<a href="http://testanything.org/wiki/index.php/Main_Page">Test Anything Protcol</a>) is Perl's simple test output format for reporting (amongst other things) success & failure of test assertions. This output is what you see printed to screen<div><div><span class="Apple-style-span" style="font-family:georgia;"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">ok 1 - Hello</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">not ok 2 - Nothing right</span></div><div><span class="Apple-style-span" style="font-family:georgia;"><br /></span></div><div><span class="Apple-style-span" style="font-family:georgia;">One thing I wanted to do was to build an object which can be run in two modes</span></div><div><ul><li><span class="Apple-style-span" style="font-family:georgia;">As a normal test script (using Test::More)</span></li><li><span class="Apple-style-span" style="font-family:georgia;">As an object which can assert all tests are good (and confess if anything goes wrong)</span></li></ul><span class="Apple-style-span" style="font-family:georgia;">So how can I do this? Thankfully </span><span class="Apple-style-span" style="font-family:'courier new';">Test::More</span><span class="Apple-style-span" style="font-family:georgia;"> delegates to </span><span class="Apple-style-span" style="font-family:'courier new';">Test::Builder::new</span><span class="Apple-style-span" style="font-family:georgia;"> (which is a singleton instance) for its assertion code. The builder has an output method which when passed a scalar reference </span><span class="Apple-style-span" style="font-family:'courier new';">Test::Builder</span><span class="Apple-style-span" style="font-family:georgia;"> will write the TAP output to that scalar. Couple this with </span><span class="Apple-style-span" style="font-family:'courier new';">TAP::Parser</span><span class="Apple-style-span" style="font-family:georgia;"> we can scan the TAP output and confess accordingly like so.</span></div><div><span class="Apple-style-span" style="font-family:georgia;"><br /></span></div><div><span class="Apple-style-span" style="font-family:georgia;"><div><span class="Apple-style-span" style="font-family:'courier new';">use Test::Builder;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">use Test::More;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">use Carp;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">my $tap;</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">my $t = Test::Builder->new->output(\$tap);</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">ok(1, 'Hello');</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">fail('FAIL');</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">done_testing();</span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><span class="Apple-style-span" style="font-family:'courier new';">my $tap_parser = TAP::Parser->new({</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> tap => $tap</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">});</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"><br /></span></div><div><div><span class="Apple-style-span" style="font-family:'courier new';">while ( my $result = $tap_parser->next() ) {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> if(!$result->is_ok()) {</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> confess('Error during tests: '.$result->as_string());</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> }</span></div><div><span class="Apple-style-span" style="font-family:'courier new';"> print $result->as_string(), "\n";</span></div><div><span class="Apple-style-span" style="font-family:'courier new';">}</span></div><div><br /></div><div>Bingo! Now I'm sure there's a module somewhere which already does this but I like how easy this is.</div></div></div></span></div></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-55042948623246008952009-12-09T16:52:00.005+00:002009-12-09T16:58:52.196+00:00Renaming a MySQL database without having access to datafilesIf you've used MySQL then you will know this situation; your database name is wrong & MySQL does not support any kind of command like<br /><span class="Apple-style-span" style="font-family:monospace, serif;font-size:100%;"><span class="Apple-style-span" style="font-size: 13px; white-space: pre;"><span class="Apple-style-span" style="font-family:Georgia, serif;font-size:130%;"><span class="Apple-style-span" style="font-size: 16px; white-space: normal;"><br /></span></span></span></span><pre>rename database my_db to my_real_name;<br /></pre><br />In fact the only way to do this is to rename the directory name the database files are held in on the data store; or so I thought. Turns out that the rename table command comes to the rescue with this beautiful line<br /><blockquote>As long as two databases are on the same file system, you can use RENAME TABLE to move a table from one database to another:</blockquote><br />Giving us something quite simple looking like this:<br /><pre><br />RENAME TABLE my_db.tbl_name TO my_real_name.tbl_name;<br /></pre><br />Pin this together with a loop over all tables in a schema & bob is your uncle you've got a database re-namer without going anywhere near the datafiles. The thing that confuses me is why MySQL dropped support for the rename function (which is still documented) when they could have implemented it like this; I'm sure they had their reasons.Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com1tag:blogger.com,1999:blog-20751955.post-3506881862657184752009-12-08T17:42:00.006+00:002010-01-14T23:17:08.759+00:00Operator PrecedenceIt's that time again when I mention something that's already in the perldocs; this one is about operator precedence. Anyway today I found out that something like<pre>my @a = qw(1);<br />print 'Yippeee!' if ( ! scalar(@a) >= 2 );</pre>What does this print out? <i>Yippeee!</i>? Nope. The problem here is operator precedence. You may read it as the count of @a being greater than or equal to 2 and negate this (after all that's what ! normally means). Well what actually gets evaluated is ! count and then if this result is >= 2. Possible solutions to this are<pre>print 'Yippeee!' if ( ! (scalar(@a) >= 2) );<br />print 'Yippeee!' if ( scalar(@a) < 2);</pre>So the first deals with it by adding () to make sure the evaluation order is respected, the second replaces it for a more logical test.<div><br /></div><div>What is the take home message? <b>Everything in Perl has a precedence order.</b></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-55059087843059123602009-12-02T12:57:00.003+00:002009-12-02T13:13:11.922+00:00each() in Perl can be dangerousI'm a Java programmer by trade and one of the first things that is hammered into us (right after never using + for multiple string concatenation) is how to correctly iterate through a Map. Now the reason why is if you want to iterate through a Map's contents using keys only and then performing the value retrieval using its get() method then that is really inefficient. Java's hash implementations are good but considering the majority of the time keys are stored with their values in the backing datastructures; to get the pair out at the same time makes sense. So the first time you come to Perl you think <blockquote>how on earth do I iterate through a hash?</blockquote> and then you see the each() method. This gives rise to the following code:<br /><br /><pre><br />while( my ($key, $value) = each(%my_hash)) {<br /> print $key, '->', $value, "\n";<br />}<br /></pre><br /><br />This all seems fine & dandy until we want to do something like this:<br /><br /><pre><br />our %my_hash = (a=>1,b=>2);<br />my @elements = get_from_somewhere();<br />print "Starting\n";<br />OUTERLOOP: foreach my $el (@elements) {<br /> while( my $key, $value) = each(%my_hash)) {<br /> print $key, "\n";<br /> if($key eq 'a') {<br /> last OUTERLOOP;<br /> }<br /> }<br />}<br /></pre><br /><br />Still seems okay right? Wrong! See the problem here comes from iteration of the <span style="font-style:italic;">EntrySet</span> belonging to the hash & not to another data structure so on multiple invocations of this code the iteration of the map continues from where it left-off. So if the elements from the hash are returned in the order a,b & we execute it twice you will see:<br /><br /><pre><br />Starting<br />a<br />Starting<br />b<br />a<br /></pre><br /><br />To get to the correct <span style="font-style:italic;">expected</span> output you need:<br /><br /><pre><br />our %my_hash = (a=>1,b=>2);<br />my @elements = get_from_somewhere();<br />print "Starting\n";<br />OUTERLOOP: foreach my $el (@elements) {<br /> foreach my $key (keys %my_hash) {<br /> my $value = $my_hash{$key};<br /> print $key, "\n";<br /> if($key eq 'a') {<br /> last OUTERLOOP;<br /> }<br /> }<br />}<br /></pre><br /><br />So what's the solution? Well if I said never use each then I would be stupid & wrong. each makes sense. What I would recommend is if you might break out of a loop using a data structure where you may require early termination of a hash structure which is persistent between calls then <span style="font-weight:bold;">do not use each</span>. Or use one of the Iterator functions/modules in CPAN to provide a more Java like method of access to hashes; but then that wouldn't be Perl :).Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com2tag:blogger.com,1999:blog-20751955.post-66867465661308117112008-08-27T20:27:00.001+01:002008-08-27T20:28:55.442+01:00Singletons; those silly little SingletonsMiško Hevery recent series of articles about <a href='http://misko.hevery.com/2008/08/25/root-cause-of-singletons/'>Singletons & singletons</a> (note the capitalisation) is one of the best discussions of the topic I have read. In the latest article he has hit the preverbal nail on the head with the distinction between a Singleton & a singleton.<br /><br /><strong>Skip to the end for a quick summary</strong><br /><br />I have worked with a lot of code containing a lot of Singletons, many caused by my own hand, and they have one thing in common. <b>They all sucked</b>. Sorry let me quantify that horrendous statement; the fact that the object(s) were Singletons made working with the code in an environment other than production nigh on impossible. The underlying code was sound. What was using the <code>Singleton.getInstance()</code> accessor rather than forcing code to pass a reference to the object which at one point so happens to be a singleton. Imagine these scenarios:<br /><br /><pre><br />public class MyClass {<br /> private final Singleton sing = Singleton.getInstance();<br />}<br /></pre><br /><pre><br />public class MyClass {<br /> private final Singleton sing;<br /> public MyClass(Singleton sing) {<br /> this.sing = sing;<br /> }<br />}<br /></pre><br /><br />Wow so it's the same overall effect (an instance of Singleton makes its way in MyClass) but the second one is just plain better. Get your Singleton to implement an interface & then you've succeeded in a decent level of separation (which is what my group did with the last Singleton). But there was one thing that I was confused about (but did not know) & it's very similar to people who hate Javascript. A singleton (a single instance of an object) is a very good thing; a Singleton (a globally held reference to a single instance of an object) is not & never will be. However a program needs a context to run from (which is what the Singleton was being used for). <br /><br />Just think about something like Struts (1.x); there's only normally one instance of an ActionServlet per application. A <em>context</em> if you will. This is where Miško's article has really driven this point home. A single instance of an object is no bad thing; in fact it's normally quite a desirable thing. What hurts you is the Singleton anti-pattern. It becomes gospel; the alpha and the omega and trust me you do not want to program yourself into this cul-de-sac.<br /><br />Anyway to summarise <strong>Singleton bad; single object instance good</strong>.Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com1tag:blogger.com,1999:blog-20751955.post-50884727092654230222008-06-30T21:44:00.003+01:002008-06-30T21:48:58.154+01:00Another Perl Snippit<div><span class="Apple-style-span" style="font-family: 'courier new';">use Test::Simple tests => 2;</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><span class="Apple-style-span" style="font-family: 'courier new';">my $array_with_things = [0,1,2,3,4,5,6,7,8,9];</span><div><span class="Apple-style-span" style="font-family: 'courier new';">ok(scalar(@{$array_with_things} == 10) ;<br /></span><div><span class="Apple-style-span" style="font-family: 'courier new';">@{$array_with_things} = (); # Here's the magic</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">ok(scalar(@{$array_with_things}) == 0);</span></div><div><br /></div><div>That's right it is a way of clearing an array of all elements. I always forget how to do it which is why it's here.<span class="Apple-tab-span" style="white-space:pre"> </span></div><div><br /></div></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com2tag:blogger.com,1999:blog-20751955.post-34664350873108175992008-03-04T20:35:00.002+00:002008-03-04T21:07:51.826+00:00I wouldn't let it lieSorry that last article has really gotten to me. I really do not want to do down people's efforts on these Perl to Java projects because I can see that there has been a lot of time spent on them. It is just that this article is recommending me to use a language which to be quite honest is not a good fit for Java. A lot of these libraries seem to have been conceived about 3-4 years ago when there was a lack of an actively developed scripting language (well there was Jython but that was not being actively developed by then). But now we've got:<div><ul><li>JRuby</li><li>Jython (being developed again)</li><li>Groovy (which really is scriptable Java with lots of sugar)</li><li>Rhino</li></ul>I look at the list of libraries and really there's something each of these languages which can do a lot better not to mention running in the JVM. In a way the author is right these are 10 modules a Java programmer should know about if only to remind themselves that there has got to be a better way now.</div><div><br /></div><div><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-style: italic;">BTW I like Perl. I like it a lot :-)</span></span></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-13195755851972045152008-03-04T16:38:00.003+00:002008-03-04T16:59:16.424+00:00Wow ... seriously?I've just had the misfortune to read an <a href="http://www.builderau.com.au/program/java/soa/10-Perl-modules-all-Java-developers-should-know/0,339024620,339286486,00.htm">article</a> about how to use Java from Perl. Maybe I am missing the point here but that sounds like one of the most awful things you could possibly do. I've spent the past 5 years working in bioinformatics (an industry where Java & Perl are the major players outside of algorithm work) and not once have I ever thought "I wish I could use my Java in Perl".<div><br /></div><div>It's amazing really but I've encountered this exact problem of Java to Perl communication over the past 3 weeks the final decision was to communicate using JSON & then leave Perl to work over the incoming JSON data. This works brilliantly and we have a very clear separation of concerns between Java & Perl. Java gets the data, passes it into Perl & then Perl can manipulate it to it's hearts content. It's even good for testing since we have canned JSON files with data.</div><div><br /></div><div>Now if it was a Perl implementation in the JVM I think I'd be more interested; but for the moment I think I'll pass on these modules.</div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com1tag:blogger.com,1999:blog-20751955.post-21120564529508198812008-02-12T10:10:00.000+00:002008-02-12T10:22:20.151+00:00A Perl of Wisdom for MeEvery so often I find a really nice construct I didn't know existed in Perl and I can never remember it. Well I'm going to post them here and see if it kicks my memory into gear.<div><br /><div> </div><div><span class="Apple-style-span" style="font-size: medium;"><span class="Apple-style-span" style="font-weight: bold;">Copying an array</span></span></div><div><br /></div><div> </div><div><span class="Apple-style-span" style="font-family: 'courier new';">my $array = [1,2,3]; # From somewhere</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">my $copy = [@{$array}]; #De-reference array into an anonymous array & assign</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div> </div><div><span class="Apple-style-span" style="font-weight: bold;">Populating a hash from an array via a slice</span></div><div> </div><div><br /></div><div><span class="Apple-style-span" style="font-family: 'courier new';">my %hash;</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">my @keys = qw/ key key2 key3 /;</span></div><div> </div><div><span class="Apple-style-span" style="font-family: 'courier new';">@hash{@keys} = (); #Populate hash with keys and no values</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div> </div><div><span class="Apple-style-span" style="font-family: 'courier new';">#Populate hash with keys from array and values from same position in the assigned list</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">@hash{@keys} = (1,2,3);</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div> </div><div><span class="Apple-style-span" style="font-weight: bold;">Copying one hash to another</span></div><div> </div><div><br /></div><div><span class="Apple-style-span" style="font-family: 'courier new';">my $input = {key => 1, key2 => 2, key3 => 3};</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">my %target = (key, 4);</span></div><div> </div><div><span class="Apple-style-span" style="font-family: 'courier new';">#And now for the copy magic</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';">@target{keys(%{$input})} = values(%{$input}); #1 deref is better than 2 but is ok for tiny calls</span></div><div><span class="Apple-style-span" style="font-family: 'courier new';"><br /></span></div><div> </div><div>Anyway I hope this is of use to someone other than me. If not then it'll be of some use to me.</div><div> </div></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com1tag:blogger.com,1999:blog-20751955.post-68586333448622956222008-01-29T21:51:00.000+00:002008-01-29T22:10:58.187+00:00You know when you just think 'Oh FFS'I've just had one of those moments thanks to an article on <a href="http://chaoticjava.com/posts/gc-tips-and-memory-leaks/">Chaotic Java</a> (if you're interested in Java then have a look through the archives as it's all gold). Anyway the article is about Java GC & there was a section about using object reference queues instead of a finalize block (a good idea anyway) and there was a line:<div><br /></div><div>I made NativeImage and Image implement Closeable, a new interface in Java 5 for IO classes that need to be closed.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">What</span>?!? There's a ... a ... interface called Closeable. Oh yes there is <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/Closeable.html">introduced in Java 1.5</a> and it's been added to just about every IO class. Wish I had know about that before writing the same <span class="Apple-style-span" style="font-style: italic;">try finally </span>block for Readers, Writers, InputStreams & OutputStreams. I know it's a case of 20 lines instead of 3 but it seems annoying. I wonder how many more of these interfaces there are in Java 5 & 6 that could have saved me a few more lines of code. </div><div><br /></div><div>Oh well</div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-81142415958503362732008-01-28T17:25:00.000+00:002008-01-28T17:59:01.422+00:00A less sucky Maven; yes please!Don Brown has posted an article detailing his <a href="http://www.jroller.com/mrdon/entry/making_maven_2_not_suck">grips</a> about <a href="http://maven.apache.org/">Maven2</a> (for those who do not know Maven is a decent Java build tool but is a bit XML happy). Anyway rather than people like me (who moan but twiddle their thumbs) Don has gone & done something about it.<div><br /></div><div>I can't wait for some of these other fixes coming through especially the one concerning making it easier to write plugins. Do that & I'll be very tempted to write an equivalent to assembly that lets you create deployment tarballs.</div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-64073360298486966392008-01-24T20:44:00.000+00:002008-01-25T13:04:37.277+00:00Wow is this my blog?<span class="Apple-style-span" style="font-family:'times new roman';">Has it been that long since I decided to do a blog? Bleedin' heck. What is more worrying is that I've decided that I should start it up again; is it really "starting it up again" if I never really started?<br /></span><div><br /><div><span class="Apple-style-span" style="font-family:'times new roman';">Hopefully it won't be another 2 years until I do my next post (I'm really hoping that it'll only be a few days). Anyway see you all soon whoever you are ... why are you reading this rubbish unless you're a friend and about to take the mick out of me; oh that'll be a nice change</span></div></div>Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.comtag:blogger.com,1999:blog-20751955.post-1136852551281010022006-01-10T08:22:00.000+00:002006-01-10T00:22:31.290+00:00Hello Len!Well it's the normal first post to these things so hell blogspace ... what a crap start hey. Anyway hope that this is going to get better which it won't do and I'll get bored in a bit. If you're wondering who I am well I'm a <span style="font-style: italic;">"Java Programmer "</span> from England (honest guv). I also love beer and chocolate.<br /><br />Well enough with introductions lets get on with what blogs are meant for; giving the unwashed masses on the internet a voice which we really don't want to hear. Anyway sod it let's go :)Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0tag:blogger.com,1999:blog-20751955.post-1136853282404366432006-01-10T00:32:00.000+00:002006-01-10T00:34:42.416+00:00Tapestry 4.0 ReleaseWhat a day! Tapestry 4.0 has been released a web framework I have never had anything to do with before but it looks fun; the kind of fun which can also involve rusty pliers :). Anyway found this interesting link to a <a href="http://www.agileskills2.org/EWDT/">manual</a> on Tapestry 4.0 & 3.0. Not sure if it's good but what the hell it's free for the first four chapters and that's a lot cheaper than ... well paying for it. Enjoy.Andy Yhttp://www.blogger.com/profile/07963397209370734274noreply@blogger.com0