Home
WWWWolf's LifelessJournal
Random ramblings of a random wolf
Recent Entries 
6th-Dec-2008 01:12 pm - Unix shell woes
Okay, I'm getting really scatterbrained.

Here I am, deeply concerned that the Rails developers will declare something obsolete and dead and buried while I'm not updating my stuff, and decide to finally fix my Rails app to use Rails 2.0 .html.erb file extensions rather than Rails 1.0 .rhtml.

Before I do the move properly, I decide to go experiment a little bit...

find app -name '*.rhtml' -exec echo `echo -ne '{}' | perl -pe 's/\.rhtml$/.html.erb/gi;'` \;

And guess what I get back? A list of files with .rhtml extension. NOT .html.erb.

In my n years of perl-fu, I have never seen something this simple blow up. I can't believe my frigging eyes. I replace '{}' with '{}.rhtml' and what do you know, I get a giant bunch of files with .rhtml.html.erb extension. Twiddling with the regex doesn't do a damn thing: .rhtml, Repeat the previous command with  > imgonnaopenthisshitwithgoddamnhexeditor.txt tacked in the end, and after doing as suggested, nothing is any more clearer.

How can I possibly fail at this???

...and after good 20 minutes I notice, oh, it's that goddamn it's-interpreting-that-{}-as-literal-except-when-it-isn't thing. Basically, echo -ne '{}' here somehow echoes, um, {} instead of the file name. Doesn't really matter if it's quoted or not, it somehow does it anyway. Perl somehow reads that in and the whole shell expression still manages to spit out the original file name somehow.

It's probably some part of a shell / find(1) weirdness that I haven't yet understood. Over 10 years and I still don't understand the subtleties of find -exec. *sigh*

So here's what actually works:

for i in `find app -name '*.rhtml'`; do git mv "$i" `echo -ne "$i" | perl -pe 's/\.rhtml$/.html.erb/gi;'`; done

Not as clever, but got the job done...
25th-Aug-2008 03:10 pm - Iteration of pain
You know, I thought Java's XML DOM implementation was hilariously boneheaded in that it reimplemented lists (badly). What made people think this is a good idea? "Oh, I'm sure Java doesn't have obscure programming concepts like Lists. Let's implement our own! Iterators? What are these blasted newfangled contraptions you speak of?" You have to use ugly hacks to Process Stuff.

So today, inspired to see what PHP 5's new, amazing XML support looks like... I find out that they've rewritten arrays so that they don't work with PHP's neat simple iterator-equivalents and you have to use ugly hacks to Process Stuff.

Please stop the planet and throw out whoever came up with this...
1st-Jul-2008 11:43 am - Slowly learning to tolerate Python
Sorry if this sounds like an irrational flame - perhaps it is. I'm still in the process of cooling down...

For me, Python has been a language that I really have divided opinions about. It's probably an important language, and in many ways, it's quite elegant; yet, at the times, I feel that the designers had no idea what they were doing. Perl can get ugly and P5 is pretty outdated and certainly out of fashion, but at least it's designed. Ruby is inefficient, but at least it's got a very clean syntax. Python? Sometimes it's cool, sometimes it's hell, and as with all languages, the makers of libraries may or may not know where they're heading. Well, at least it's far better than PHP. =)

A few days ago I wrote a script to replace my old shell script that fires up WLAN connection with specified settings. Whee - I learned of Python shell help() feature. Damn, that's cool. (The reason I didn't use it before was that I thought help()s are useless. if it was called interactive_documentation() I might have paid attention. =) If it can one day do something similar to Ruby's (Class or object).public_methods.grep(/whatever/).sort, I'd be in heaven. In my opinion a good language is self-documenting and browseable.

Anyway, I ported my earlier GIMP bloom script to Python-Fu. While I like some of the OO stuff, some of the stuff is pretty weird, and certainly doesn't match with the documentation I had at hand. I'd offer some random comments from the source code - censored, because the script was, after all, posted on deviantART - and I thought that now that I've slept over night, I might actually talk about the problems in a calm and collected fashion.

For some background: GIMP's promary programming interface is the Procedural Database (PDB), which is basically a standard set of calls that GIMP understands and you can call them no matter what language you are programming in - the same calls work in Scheme (Script-Fu), Perl (Perl-Fu), and Python (Python-F... excuse me, GIMP-Python.) However, Perl and Python APIs also include an object-oriented API for some internal GIMP objects, like images and layers. Obviously, you want to use the OO API as much as possible - especially in Python, the Superiour OO Programming Language®.
Why the [censored] are the [censored] parameters in different order compared to gimp_layer_new PDB call? Just for [censored] fun? Not very funny to me, [censored]! I like to stare at PDB browser, and if the parameters are not in that order, well, [censored]!
For some obscure reason, the standard gimp_layer_new PDB call and Python gimp.Layer OO constructor take parameters different order. Same for other stuff, like channels and images and whatever. Not a biggie... I just need to keep two sets of documentation open; one for the GIMP OO API, and the PDB browser. You see, if the arguments were in same order, I could easily take whatever it says in gimp_layer_new call documentation and just stick gimp.Layer(...) there instead.
Why the [censored] do I get a [censored] type mismatch when doing the non-PDB version of the command? Exactly as said in spec! And more [censored] importantly, which [censored] argument triggers that [censored] error??? [censored] Python only says "type mismatch", yeah, as if that's going to get me [censored] anywhere.
selchn = gimp.Channel(img,"For selection",width,height,100,(0,0,0)) doesn't work. selchn = pdb.gimp_channel_new(img,width,height,"For selection",100,(0,0,0)) works perfectly. One comes from Python-Fu documentation, exactly as specced. Another comes from converting the Perl PDB call directly to Python PDB call - ugly, because Python scripts should probably use the neat API instead of raw PDB when the neat API is available... but either way it gets the job done, and it's done exactly as specified too. What's wrong with this picture?

I have no idea what causes the "type mismatch" error here. The Python API doc also says the last argument should be "...colour (one of the *_CHANNEL constants)". Er... Script-Fu and Perl-Fu want, uh, er... you know, a colour as the last argument. One that specifies the channel colour, you know. And obviously, the *_CHANNEL constants aren't listed anywhere in the spec... so a quick grep says legit values are PF_CHANNEL and PDB_CHANNEL, neither of which work. What the shit? I don't know about you, but I get a nagging feeling that maybe the spec is wrong. Very wrong.

Then a pop quiz. How do you paste stuff in Perl?
my $fs = gimp_edit_paste($selchn,1);
$fs->anchor();

Yeah, pretty simple. The script was done in Perl::Fu style, but can mix OO style in if it makes sense. Now, how do you paste shit in Python?
fs = pdb.gimp_edit_paste(selchn,1)
pdb.gimp_floating_sel_anchor(fs)
"OO is failure, OO is failure, tralla la lalla la lalla la!" Excuse me, you can't anchor a floating selection via an OO call in this allegedly Superiour OO Programming Language®, you have to use one of those evil no-good PDB calls.
[censored] Python-Fu needs the [censored] list length, which Perl-Fu can figure out on its own. I can't [censored] believe this [censored]!
In Perl, the call is in form gimp_curves_spline($selchn,0,[127,0,254,254]); This deviates from the PDB standard, because it is missing the list length argument... which makes sense, because the list length argument isn't needed anywhere else either: the PDB idiom is always, everywhere, "list length argument followed by list itself", and Perl automagically hides this. If the PDB idiom doesn't make sense in the target language - e.g., in Perl, you certainly always know how long your lists are - there's no reason to not change it. Especially if it doesn't really change the way stuff gets called: PDB wants to know the "list length and list itself", and doggone it, Perl can provide it for you. If you are programming in some crappy language, yeah, then passing the list length makes and awful creepy much of sense.

So what does Python want? pdb.gimp_curves_spline(selchn,0,4,[127,0,254,254]) ... um, did I just see list length argument? Did I just see a bloody list length argument? This isn't some shitty language like C where you have to be super-careful about list lengths, you know! This is the Superiour OO Programming Language®! Goddamn it.
Another [censored] type mismatch, even when the reference says you can specifically feed it None to say no channel is active... Oh well, don't blame me if this blows up!
I thought it was nice to tell GIMP that active channel is not active... in a proper OO fashion. img.active_channel = None should do the trick, right? That's what the spec says, right? Blam! Type mismatch! Cannot assign that here! The spec is looking rather weird right now!

All in all, converting the script to Python-Fu wasn't that difficult... but I still can't quite shake away the feeling that something is not really all that well designed here.
1st-Feb-2008 08:11 pm - Head on toward niftylittledom wall
About 10 years ago (everything happened about 10 years ago) I made a fool of myself. Someone on some Linux forum asked about databases available for Linux and I was so proud to pitch them Perlette, the database program that I had written.

My first really major Perl application! You could create all sorts of nifty databases on it! They could have records with fields and stuff! And you could search the thing! And add and delete records! It clearly beat the snot out of Cardfile!

Soon, I read about the databases the Big Boys were using. I read about SQL. I read about relational databases. A sudden realisation came to me: My little database was pretty quaint, but essentially absolute shit for any real purpose. I emerged from the experience a little bit wiser.

Essentially, the big things I learned:
  1. I failed to consider the option that someone might have done things a little bit more elegantly. Consequently, people will expect features that are in the stuff the Big Boys are using. They don't care about your little piece of crap if it doesn't have the features the Big Boys have in their databases.
  2. Progress will happen even if I'm not there to witness it. To me, databases were still Cardfile and DBase. I had no idea awesome things like MySQL or PostgreSQL were heading this way like giant big locomotives.
Oh well, I didn't single-handedly revolutionarise the industry that day. Maybe some other day.

I was always kind of struck by that memory. On The Daily WTF forums, someone's apparently reliving that experience. Painfully. Apparently, whatever happened to me can happen to everyone else. At least I didn't get a bloody 23-page thread for my stupid program!

Hmm - I also plan to one day publish Boot 64, the awesomely awful multi-user program shell/email application for Commodore 64. Written in goddamn BASIC. My god, was that thing innovative as hell. Bet no one would have used it for real, but my friends and I loved it. =) I will not claim it had any revolutionary ideas...
14th-Jul-2007 03:41 pm - Macros are fun, macros aren't fun
The situation is basically this: I've come to the conclusion that writing scripts for OpenOffice.org is Not Funny. I need some better ways of handing OpenDocument files; OpenOffice.org makes writing scripts in any languages completely difficult and obnoxious.

Let's see, for example, how to properly record a macro in a sane environment. The comparative task is simple: Add text string "boring day" in a document, new line, select all, then replace "boring" with "carnival".

Here's how a sane environment records such thing:

// This is a recorded macro. First, check over the
// commands to make sure this is what you intended. Then,
// save this buffer, and the macro should appear in the
// Macros menu.
textArea.setSelectedText("boring day");
textArea.insertEnterAndIndent();
textArea.selectAll();
SearchAndReplace.setSearchString("boring");
SearchAndReplace.setReplaceString("carnival");
SearchAndReplace.setBeanShellReplace(false);
SearchAndReplace.setIgnoreCase(false);
SearchAndReplace.setRegexp(false);
SearchAndReplace.replace(view);


No, this doesn't seem cryptic at all... Search-and-replace commands get a bit verbose, but that's not the big problem. The "sane environment", here, is jEdit, which uses BeanShell as its scripting language. BeanShell is not a shabby language, actually. This is only marginally more than what code I'd need to write for Emacs if I wrote an elisp command by hand...

So what does OpenOffice.org do? Yep, they support BeanShell, they support JavaScript, a whole lot of languages - but the macro recorder only does StarBasic, its own peculiar brand of code. And what the crap does it generate?

sub TestMacroRecording
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "boring day"

dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:InsertPara", "", 0, Array())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array())

rem ----------------------------------------------------------------------
dim args4(18) as new com.sun.star.beans.PropertyValue
args4(0).Name = "SearchItem.StyleFamily"
args4(0).Value = 2
args4(1).Name = "SearchItem.CellType"
args4(1).Value = 0
args4(2).Name = "SearchItem.RowDirection"
args4(2).Value = true
args4(3).Name = "SearchItem.AllTables"
args4(3).Value = false
args4(4).Name = "SearchItem.Backward"
args4(4).Value = false
args4(5).Name = "SearchItem.Pattern"
args4(5).Value = false
args4(6).Name = "SearchItem.Content"
args4(6).Value = false
args4(7).Name = "SearchItem.AsianOptions"
args4(7).Value = false
args4(8).Name = "SearchItem.AlgorithmType"
args4(8).Value = 0
args4(9).Name = "SearchItem.SearchFlags"
args4(9).Value = 71680
args4(10).Name = "SearchItem.SearchString"
args4(10).Value = "boring"
args4(11).Name = "SearchItem.ReplaceString"
args4(11).Value = "carnival"
args4(12).Name = "SearchItem.Locale"
args4(12).Value = 255
args4(13).Name = "SearchItem.ChangedChars"
args4(13).Value = 2
args4(14).Name = "SearchItem.DeletedChars"
args4(14).Value = 2
args4(15).Name = "SearchItem.InsertedChars"
args4(15).Value = 2
args4(16).Name = "SearchItem.TransliterateFlags"
args4(16).Value = 1280
args4(17).Name = "SearchItem.Command"
args4(17).Value = 3
args4(18).Name = "Quiet"
args4(18).Value = true

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args4())


end sub


What the hell is this?

Let me repeat that question again: What the hell is this?

Yeah, we explicitly have to define "yes, we're dealing with documents here." We're using cryptic superfluous structures; nope, we can't possibly just call a simple method somewhere with sensible parameters, we have to pack our information in a giant JavaBean and then "execute dispatch" of this operation with this elaborately packaged piece of junk. Brilliant. Just brilliant.

"Oh", replies the word processor's info desk, "current documents being edited can be found on the ThisComponent.CurrentController.Frame counter, and if you want to actually do anything about it, you need to hire a dispatcher. For that, be sure to fill the form titled createUnoService("com.sun.star.frame.DispatchHelper")."

"What's a dispatcher? And what's an 'uno-service'?" asked the user.

"I don't have time to explain, but it will make itself apparent soon enough. Did you remember all that?"

"No, heck, no. I just wanted to make a macro. Now I need to file tons of paperwork with cryptic Java class names with full package names - obviously sticking import whatever.*; there by default was too challenging. I can never remember this stuff, let alone figure it out, if I have to do it by hand."

"Don't you worry, we have wonderful macro recorder to do this stuff."

"Actually, this macro recorder sucks", said the user. "I tried to change a document language, and it didn't save any commands."

"Oh, well, a few corner cases here and there. You can always write your own macros!"

"I tried that", said the user. "The documentation is hard to find, doesn't cover other languages, and things that are supposed to be accessible aren't - I have no idea how to change document styles nowadays. There's no auto-completion of referenced object methods and fields a la Eclipse, no on-line class browser or M-x apropos or interactive interpreter à la irb or python or any Lisp implementation, so all I can do is type some random crap based on educated guesses run the macro and hope for best..."

...sorry for the narrative, but that was essentially what happened here.
27th-Feb-2007 09:59 pm - Version control stuff
[info]premchai21 got me inspired about checking out what darcs has to offer over Subversion. The idea of a distributed version control seems to sound like a good idea.

Darcs seems extremely nifty and I probably will use it for some projects. However, I won't move away from svn entirely.

One big thing is that I have a bunch of crap in my big svn repository. Tiny little repositories of projects that didn't really fly. What seems to be cool about darcs is that I can

The docs on this topic seems to have a few good points. Lack of partial repository checkout (svn co repo://blah/trunk/some/damn/path smallcheckout) is a big turnoff though. For example, I have one SVN repository that has random config files; I check out ~/.randomapp/ from there and ~/.anotherapp/ from there and things are just fine. Also, I keep different websites in same repository...

Apparently, according to the FAQ, darcs also has a weird procedure for nested/external repos, so no hope of getting seeing anything similar to svn:externals...

The page says that SVN's advantage is that "Subversion has a working GUI". Bloody goddamn darn! CVS has some almost halfbaked GUIs, Subversion's GUIs absolutely stink, and if darcs' GUIs are worse, things are not nice...

Not a big turnoff, but darcs seems to be "amazingly crossplatform". No ".darcs", which would be a  hidden directory in some OSes. However, it seems democratic - "_darcs" is not hidden in any OS and will look equally ugly everywhere. =)

Okay, I'll report about some of my impressions later. The feature list seems interesting though.
20th-Oct-2006 06:42 pm - Holy darn! Writing search is easy!
As I've probably written before, I'm writing a tool for Ultima VII translation. It's based on an earlier engine written by the French Serpent Isle team. Basically, that was a quick, for-hackers-by-hackers, if-it-goes-boom-just-hit-it-until-it-starts-working tool written in PHP and MySQL. So, I wrote a new tool. In Ruby on Rails and PostgreSQL. Setting it up is still a pain, but at least it's... well, complex, and smooth to use.

The PHP hack had one redeeming feature my translation tool didn't have. Full search.

How the heck do I implement full search in my application, I wondered...

...until I found out stuff like "Hmm, seems like some MediaWiki extension uses Lucene, wonder if Lucene has Ruby bindings?"
"...oh, seems that Lucene bindings for Ruby are called Ferret, how quaint."
"Okay, seems like Ferret is really easy to make index stuff, and it can index metadata in a sensible way. So, it's a matter of a few gymnastic moves to add Ferret to..."
"...wait a second..."
"...wait a frigging second..."
"...it can't be this easy..."

Holy. Cow.

I dialed up the plugin.

I added a line saying "acts_as_ferret" to two model files.
My data is ready to be indexed.

I added a search controller, with grand total of two search calls. I could do just one, apparently.
My data is ready to be searched.

Then I spent 45 minutes writing an UI for this stuff, because I was dumb and Ruby has a bit funny string syntax for someone with Perl background, but hey, live and learn.

And now I have a search box in my application!

Thanks, Apache Project, for simple search stuff. =)
14th-Sep-2006 09:48 pm - Eternal Noob looks at Java again
Okay, here's the problem: I needed a dictionary application for my spurious conlang efforts. XEmacs isn't always helpful and I hate the textual format that dictd needs. So, I'd better design a GUI tool which can use rich text (bolds and italics), save the stuff as xml for internal use, and there we go.

Try 1, a few days ago: Okayyyy... it's bloody easy to design the GUI with Glade. It's damn difficult to program the bloody application in Ruby. I still don't get how this bloody ListView works. There's apparently an example of it, but... uh... eh... argh. This project would have succeeded if I had not been scared for no reason...

Try 2, today. Just for the heck of it, I started writing the app in Java. Using the much-maligned javax.swing.*;. At first, I was thinking "no way, this is never going to work.

Two hours later, I sit here with a half-done application.

Just need to write stuff like sorting, saving, loading, and dictd export, but that's simple, right?

I can't escape it: For some obscure reason, Java AWT and Swing are just about the only GUI toolkits that I have really "got". Wonder what's so bad anout them. They sure aren't as slow as they used to be.

Interestingly, this was probably my first look at Java 5.0's new GTK+ Swing look-and-feel. Basically, it looks nowhere like GTK+. Oh, yeah, it looks like GTK+ on default theme. Just that nobody uses GTK+ on default theme when Clearlooks has been invented. If Sun is really serious about GNOME and stuf, they really, really, really needs to consider hurrying up. Wonder how annoying this app would be to port to SWT. Oh, and it seems that this app compiled just fine on gcj but the UI was weird...

</geekspeak>
14th-Sep-2006 12:50 pm - Rails + Eclipse woes
I love Eclipse. I love Ruby and Rails. I love Subversion. But together, these three things make life living hell.

I have the highest respect for Rails development team, but I'd like to question one design decision: vendor/rails.

What's the bloody idea of linking to the development libraries from the project? The IDE notes "oh, here's a bloody lot of Ruby files. Let's index them." And then it goes chomping the files for our perusal. That, combined with the fact that Subversion module is kind of sluggish on Eclipse - does work, but operating on average to large source trees is slowish. Opening up Rails project in Eclipse takes bloody months.

Alternatively, I wish Eclipse would have the option to make some folders not "part of the project". I.e., I'd say "vendor/rails contains f*load of s*t that has absolutely nothing at all to do with the project."
24th-Aug-2006 03:30 pm - Random computer voodoo
There was this recent debate about "computer voodoo".

I replied with a comment telling about my weird C64 copy protection issues.

Some other things that might be of note:


  • Now, on golden old days, I had a HP DeskJet, which was a decent enough printer and it was back when inkjets didn't suck. You could actually make sense of what the printer was doing by just listening to it. "Okay, now it's almost ready to print. Now it feeds in paper and starts printing." A year or so ago, my parents bought a Canon inkjet printer... which had the annoying side that you can make absolutely no sense what it's doing just by listening to it. "Uh, it moved the print head back and forth. Now it moved the print head to right side. Now it moved it to the center. Now it moved it back and forth. Wonder when it starts to print? Okay, now it moved it to the side again. Oh, look at that mysterious orange lamp that blinks with funny morse code stuff again! I guess it failed to start printing. Wonder what that means?" *sigh* If I ever buy a printer of my own, it'll be a HP laser printer... with an LCD display.

  • I have extremely hazy recollections of this one, but one time, I wrote a C program that didn't work normally. Since gdb was for pros and I was a stinky newbie, I added printf() stuff around to see where it got and how. The program worked flawlessly. Commented out the printf() stuff, and it failed again.



...and most recently, the Technorati indexing issue. Turns out that Hobix was generating invalid Atom feed. Now it seems to index all of my blogs just fine. Finally...
This page was loaded Dec 2nd 2009, 3:57 pm GMT.