Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jdavidb (1361)

jdavidb
  (email not shown publicly)
http://voiceofjohn.blogspot.com/

J. David Blackstone has a Bachelor of Science in Computer Science and Engineering and nine years of experience at a wireless telecommunications company, where he learned Perl and never looked back. J. David has an advantage in that he works really hard, he has a passion for writing good software, and he knows many of the world's best Perl programmers.

Journal of jdavidb (1361)

Tuesday June 09, 2009
04:38 PM

Can I Inline .NET?

Anyone know how to call .NET code from Perl? :)

Tuesday May 19, 2009
11:25 AM

Java gravel of the day: substring redux

On 2008-01-25 I reported that Java's substring() method was brain damaged. On 2008-02-22, I reported that apparently I had been brain-damaged and that Java seemed to be fine and work in a sane manner.

Today I'm looking at the documentation, and I've coded a test implementation, and as near as I can see the brain-damage that I reported really is present. Give Java a second index that goes beyond the length of the String, and instead of just getting the remainder of the String regardless of its length, you get a RuntimeException. If you want to say "Give me 9 characters, or however many you've got," you get to do some math on that yourself. I hope you don't commit a fencepost error.

Here's my implementation that demonstrates this:

public class Substr {
  private String str;

  public Substr(String str) {
    this.str = str;
  }

  public String substr(int beginIndex, int endIndex) {
    return str.substring(beginIndex, endIndex);
  }

  public static void main(String[] args) {
    String str = args[0];
    int beginIndex = Integer.valueOf(args[1]);
    int endIndex = Integer.valueOf(args[2]);
    Substr substr = new Substr(str);
    System.out.println(substr.substr(beginIndex, endIndex));
  }
}

Run results look like this:

$ java Substr ABCDE 0 1
A
$ java Substr ABCDE 0 2
AB
java SubStr ABCDE 0 9
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 9
        at java.lang.String.substring(String.java:1765)
        at Substr.substr(Substr.java:9)
        at Substr.main(Substr.java:17)

I really just don't think that this is good design. But maybe I'm prejudiced. When I'm coding in something besides Perl, I don't expect the benefit of things like negative indices, but I do expect some sanity. To my way of thinking, substr(pos, len), returning up to len characters but not necessarily that many if they are not available, is a pretty common way for languages to specify this call, and is objectively better than substr(start, end + 1) or substr(start, end), and definitely better than throwing an exception for a length too long. But is this really objectively so?

Submitted the question for discussion on Stack Overflow, so we'll see how that goes.

I looked at the source for Java 5's String class and was impressed with the efficiency of the implementation of substring(). Internally a String keeps a char[] array and an offset telling where the String starts in that array; a private constructor permits substring() to return a new String that shares the char array with a new offset and length, which seems quite efficient and clever, to me. But I can see that a sane substr() would have been quite easy to implement using the same constructor; in fact, a new substr() could be grafted on with Perl's semantics (probably including negative indices) with hardly any trouble at all and no conflict with the existing substring() since the name is different.

I have only a slight idea as to why I rescinded my initial false report: I may have been looking at the other signature for substring(), which takes only one index and returns characters through to the end of the String. That's good behavior, as far as I'm concerned; I'd hate to have to work around it not being there.

Thursday May 07, 2009
09:03 AM

I'll journal about it if I want to

In fact, I might even blog.

I am tired of seeing folks gripe and moan about people who write journal entries about problems rather than sending in bug reports or contacting people directly.

People who write a post about a problem, no matter how friendly, are often subjected to vitriolic hatred, sometimes including swearing, and an attempt to shame and pressure them by appealing to some sense of "community interest." It never seems to occur to these folks that the journalists have their own interests to look out for. Maybe the journalist didn't want to serve the community for free. Maybe the journalist was simply making a note for himself. Maybe he would've filed a bug report later, when the problem was better understood. Maybe he thought the problem was his and someone would correct him in a forum and didn't think a bug report was appropriate. Maybe he's just making a record of obstacles he encountered. Maybe they simply disagree with you on what is and is not best discussed in public versus in private.

Plus, many folks seem to take this as a personal affront. Indeed "community interest" is often just an abstract notion used to shame people into supporting the speaker's interest. Cussing somebody out for writing a journal entry on use Perl instead of contacting you personally or filing a bug report or whatever else you would prefer them to do is nothing more than an attempt to shame them into acting as if they were your private slave. Don't expect people to take your interests into account if you have so little respect for their interests. And don't count on all the other individuals in the "community" to back up your bad behavior; some of us see through this crap for what it is, and don't enjoy watching it.

If two people are going to be "community" together, then it needs to be completely voluntary on both parts, and both people need to find that the relationship benefits them and enhances their goals. When a bunch of people do that in a network, it's a community, and the community is never a real thing; it's just an abstract term that refers to a giant asymmetrical network of relationships composed of individuals, each of whom has their own unique goals and desires, some but not all of which coincide at various times.

Politely notifying somebody that there's a bug reporting avenue they might not have been aware of is innocuous and often useful. Cussing somebody out for embarrassing you by blogging about how hard it is to understand your poor module documentation instead of emailing you privately just shows what a jerk you are. Don't kid yourself by pretending you are serving the "community." What you are really doing is emotionally injuring one node of the network that is your "community" in an attempt to serve your own vision of what everybody's interests should be.

Not everybody has to care about every journal entry. The author does, and that's enough. Not every journal entry has to find its way back to your version of the "interested parties." Sometimes a communicator feels better served by broadcasting instead of using point-to-point communication. If you pick up a broadcast and feel that it doesn't serve your needs as a listener, either quit listening, or take your own advice and politely contact the broadcaster if you think the two of you can work together to better meet each other's needs.

Friday May 01, 2009
11:59 AM

Bad download archive hall of shame: Quartz

Major projects like Quartz, the Java enterprise job scheduler, should know that the package you download from their site should contain one top-level directory, so that when you extract it you get one quartz/ directory containing the contents of the archive, instead of dropping files like readme.txt and directories like docs/ and src/ everywhere, when you might already have files and directories with these names.

Shame on you, Quartz. Everybody else knows this by now.

Wednesday April 22, 2009
09:38 AM

Setting up mysql client on Cygwin

I'm running Windows MySQL server, but I'm doing an increasing amount of my development work from Cygwin (thankfully). Unfortunately, to get maximum benefit out of Cygwin I want to be doing my work from xterms, and the Windows MySQL client expects to run under the Windows console. I really don't want to launch Windows consoles with Cygwin bash just for MySQL (or anything else, for that matter), and I don't want to limit myself to CMD, so I wanted to use a Cygwin-native MySQL client.

To compile the client, I had to pass --without-server and --without-libedit to ./configure . The first option's meaning is obvious. The second seems confusingly-named to me: it directs MySQL to compile using libedit already installed on the system instead of compiling libedit from source bundled in its source tree. The option does not mean you won't get command-line history or anything. In fact, command-line history works beautifully and is much more preferable to what I get from the Windows MySQL client.

After installation, the client wants to connect through a local socket. I doubt that this can be made to work from Cygwin to Windows MySQL server, but I suppose it might be as simple as needing to direct the client to look for the socket somewhere besides /tmp/mysql.sock (C:\cygwin\tmp\mysql.sock) or making a symlink. My approach instead is to tell the client to connect with TCP:

mysql --protocol=tcp

This of course is inconvenient to type every time, so I put it in ~/.my.cnf . (I used strace on the failing mysql client to determine the potential locations for my.cnf were: /etc/my.cnf, /etc/mysql/my.cnf, /usr/local/etc/my.cnf, and $HOME/.my.cnf .) The my.cnf syntax is:

[client]
protocol=tcp

Googling revealed that it was also possible to force the client to connect with tcp by telling it to use 127.0.0.1 as the host. Mysteriously, this does not work when the host is specified as localhost.

Tuesday April 07, 2009
04:24 PM

Carp in Java?

Does anyone know how to carp in Java? I'm writing a die() function which does some logging and other things and is supposed to throw an Exception, but since the Exception gets created within die() it reports die() as part of its stack trace, confusing anyone looking at it.

I'm asking on StackOverflow, but the typical Java response is "Why would you want to do that?" :)

Tuesday March 24, 2009
09:19 AM

Where's Perl Power Tools?

Google's top hit is Sourceforge, which says as of 2004 the project can be found at http://ppt.perl.org/, which is 404ed.

Friday March 20, 2009
01:46 PM

How do you run ack with Strawberry

I've just introduced one of my more enlightened coworkers to ack. He thinks it'll replace Cygwin for him entirely, and possibly even his Linux box. Only problem is, he can't get it to run with Strawberry on Windows. He and I are both mainly UNIX-literate. What do we need to do to get this set up right?

(He tried editing the shebang line, but I knew that wouldn't work.)

Update: Answer: use Strawberry's cpan command to install App::Ack, and use the ack that comes with that. I'd still like to know how to make it work for the standalone ack, though, as I'd like to know how to do this for arbitrary Perl programs in general. Apparently I'm supposed to be able to do so with the PATHEXT variable and some other manipulation, but I can't quite figure it out.

Monday February 23, 2009
08:45 AM

Java tip of the day: regex s///g (global replacement)

It's hideous, but I think it does the trick:

public static String subst(String string, String regex, String repl) {
  Pattern pat = Pattern.compile(regex);
  Matcher m = pat.matcher(string);
  StringBuilder sb = new StringBuilder();
  int prevend = 0;
  while (m.find()) {
    int start = m.start(0);
    int end = m.end(0);
    String val = m.group(0);
    sb.append(string.substring(prevend, start));
    sb.append(repl);  // sb.append(transform(val));
    prevend = end;
  }
  sb.append(string.substring(prevend));
  return sb.toString();
}

Thursday February 19, 2009
04:55 PM

File::Find::Rule, follow up

The truth is after my previous journal entry I went on to write a program that just takes the output of UNIX find. :) But I didn't finish, and I got pulled off of that project until later, so when I come back I may do something else.

Contrary to popular belief, I did not conclude that File::Find::Rule was dead!!! Nothing of the sort! I saw the date, and thought "That looks odd," and decided to ask. And provoked a great little discussion to come back to, in the process.

I actually wondered if the truth wasn't "The module is doing so well nobody's seen a need to update it since then." But I also thought it was entirely possible that work had carried on under a different name, much as WWW::Mechanize took off from its predecessor module (whose name I don't even remember at this point, but whose author was Kirrily "skud" Robert, IIRC).

I am quite glad to see that ack's approach can be accessed through File::Next. I will probably look into that at some point.