Anyone know how to call
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.
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.
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.
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
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
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:
[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.
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?"
Google's top hit is Sourceforge, which says as of 2004 the project can be found at http://ppt.perl.org/, which is 404ed.
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.
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();
}
The truth is after my previous journal entry I went on to write a program that just takes the output of UNIX find.
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.