You are viewing lionmage

Robert Poole's Journal
[Most Recent Entries] [Calendar View] [Friends]

Below are the 20 most recent journal entries recorded in Robert Poole's LiveJournal:

    [ << Previous 20 ]
    Monday, September 15th, 2014
    12:13 pm
    Embedding content from Upworthy doesn't seem to work
    Just tried embedding a link to audio of an interview with Bill Nye hosted on this site, but apparently LiveJournal insists on mangling/excising the embed code, leaving me with empty <lj-embed> tags. Kind of useless.

    The embedding for YouTube videos seems to work fine, and uses iframes just like Upworthy's embed codes do.

    At any rate, check out the link and listen to Bill Nye!

    Current Mood: frustrated
    Tuesday, July 8th, 2014
    5:29 pm
    Grails data binding sucks
    Grails has an elegant way of handling parameters passed from web forms: command objects. There are certainly other ways to pass parameters back and forth between the view and the controller (and Grails exposes a params object implicitly to all controller methods), but if you need everything contained in a single object for convenience, command objects are the way to go. You can even do some things with them that you can do with domain objects, such as constraints and custom validation logic. (Just don't declare fields with def, because apparently the binding only works on typed fields...)

    However, I'm starting to learn that there are vexing problems with Grails data binding, problems for which the solution is not obvious. For example, say I create a command object Foo with a field named abc of type String. I have a save method in my controller, Bar, which takes an explicit argument of type Foo. Grails is supposed to take all the parameters passed in through the request and bind them to the same-named fields in the command object.

    So today, as I'm writing code, I got a stack trace looking like the following:

    groovy.lang.MissingPropertyException: No such property: abc for class: blah.Foo
    Possible solutions: abc

    That's right, folks. Grails claims that the field does not exist, and then tells you to use the same damned field it just told you didn't exist. So much for custom validation logic, since the exception is being thrown within one of my validators. (I'm actually working with passwords, so the idea was to put a custom validator on the “repeat password” field which ensures that the user typed the same password both times. A ValidationException should be thrown if the fields are different.)

    I really am not sure what's causing this problem, because we have other code where binding works fine, but I seem to always trip over corner cases like this.

    Update: I was able to work around the problem using a 2-arg version of the validator closure, and refraining from directly referencing fields in the object itself. (The second arg is a reference to the object instance being validated.)

    Current Mood: annoyed
    Thursday, May 1st, 2014
    12:33 pm
    Does taking credit for destroying a startup company make you a jerk?
    I happened upon an article on TechCrunch by Milo Yiannopoulos with the provocative title, “How I Killed a Startup in 4 Hours (And Why I Don't Regret It).” There's an editor's note at the head of the article which notifies the reader that Yiannopoulos is a journalist and broadcaster, and that he will be publishing a book in 2015 titled The Sociopaths of Silicon Valley. That should serve as a warning, and an indication of how this guy feels about technologists.

    The short version: A startup called proposed to cull articles from various online sources and bundle them into a beautifully printed magazine-style format, mailed directly to your home. The per “issue” cost would be about $2, so not that cheap nor environmentally friendly, and the company proposed to strip out ads, which is how websites monetize articles. As Yiannopoulos rightly points out, there's the concern of copyright infringement, especially since the source sites were not being compensated, nor permissions obtained.

    The problem is, Yiannopoulos is also overtly hostile to technology companies, and it really comes out in this article. He makes the basic mistake of conflating copyright infringement with theft: “In other words, its entire business model is predicated on theft.” (His emphasis.) Of course, the problem is that it's being done by a third party and for-profit; there are plenty of applications and services out there that let you make local copies of articles on the web, and many of them even reformat the content and strip out ads, but all of those are for personal use, where fair use doctrine applies in the United States. (To give two examples, Amazon's Silk browser for the Kindle Fire tablets has a special article reading mode, and Evernote lets you snip just article contents on a page instead of the entire page using their Clipper plugin for browsers.)

    Here's where I think Yiannopoulos goes off the rails:
    The indifference — and occasional contempt — with which Silicon Valley treats content businesses is laughable and offensive. For all their talk of “changing the world” and focus on crafting cute interfaces, I can’t think of a single technology company in history that has made much of a lasting cultural contribution.
    Really? Well, I suppose that depends on how you define culture and technology (or “technology company”). Without railroads, we wouldn't have had streetcars (also known as trolleys, or light rail in the modern age). Without streetcars, there would be no A Streetcar Named Desire (not to mention numerous other railroad metaphors that seeped into English and other languages). The typewriter was one of the greatest enabling inventions for writers ever, replaced only in the latter half of the 20th century by the personal computer. The automobile continues to be a fascination for many, and has influenced every factor of modern culture; automobiles are also frequently viewed as works of art in their own right, and justly so.

    Computers and Computer Science have had a profound impact on modern culture too, even on mainstream purveyors of so-called “literary fiction” (a term I find elitist and offensive). Same for biosciences.

    As an aside, if it seems that many technologists and other technology-savvy people are less than thrilled with current copyright protections of content, it's that copyright law has been abused to continuously lengthen the duration of copyright (effectively making it eternal) to the detriment of the public domain, and that not all content companies are equal. For every dozen small publishers or beleaguered newspapers out there, there is one large content company wielding outsize political and marketplace influence. I'm thinking of Disney as one major example, a company its detractors sometimes refer to as the Mouse Gestapo.

    Yiannopoulos asks, What startup can boast an influence on our intellectual history equal to The Divine Comedy, or Paradise Lost, or… well, you get the idea. That's a pretty ridiculous comparison to make. First off, startup companies make up a newer, small and ephemeral fraction of all technology companies currently out there; if you want to villify an industry, you have to recognize this fact or you're just creating a straw man. Secondly, the two examples of literature he gave were old, outstanding examples of the literature of their time (think Sturgeon's Law), and not very representative of the breadth of depth of even fine literature. His comment also underscores a certain prevailing snobbish attitude that the only literature worth studying is that written by old, dead white guys — the older and deader, the better — while simultaneously comparing high art with Wired articles. It's disingenuous to say the least.

    I'm not advocating for copyright infringement, though I have advocated for saner copyright durations in the past. I believe that had a questionable business model (the unauthorized distribution aspect particularly bothered me), and should have vetted its product idea with lawyers before launching. That's expensive, and a legal hurdle that many garage startups can't make without VC money, but these guys apparently could have done that and didn't. But I don't think it's fair to turn around and tar the entirety of Silicon Valley and the rest of the tech world.

    One last thing... the use of the term sociopath is very loaded, and I hope Yiannopoulos has a change of heart and chooses a different title for his upcoming book. First, the term is of dubious value in psychiatric circles. Second, the term is often misapplied to people on the autistic spectrum, and we know that Silicon Valley (and the tech industry at large) has quite a few high-functioning people on that spectrum. The difference is that sociopath has negative connotations, and implies intention to do harm. That's yellow journalism, in my not-so-humble opinion.

    Current Mood: surprised
    Monday, March 10th, 2014
    3:56 pm
    Wolfram is at it again
    It appears Stephen Wolfram is at it again, this time creating a language called (big surprise) the Wolfram Language. Apparently, it's not enough to name almost all the company's other products after himself and publish papers in journals that themselves are published by his own company...

    The Slate article linked above spends a fair time trying to be fair to Stephen Wolfram and his new language, although the author can't resist providing links to one of my favorite criticisms of Wolfram and his book, A New Kind of Science.

    It isn't long before David Auerbach starts to tell us what he really thinks: But when Wolfram says that his language knows about the world, it’s sleight of hand—no different from saying that the English language knows about the world because it happens to have words used in the world.

    And even more telling, here's the money quote:
    Bottling all this real-world data together with the language has another, more pernicious side effect. If I want to use a different knowledge base with Wolfram, or use Wolfram’s knowledge base with a different underlying language, I can’t do that unless Wolfram gives the go-ahead, because he has locked all the pieces together. Given Wolfram’s penchant for suppressive legal threats around intellectual property, I recommend against building anything in the Wolfram Language, lest Wolfram decide that he owns it.

    Auerbach then likens Wolfram's hyperbolic claims about this language's knowledge of the world to what he calls inflated claims about artificial intelligence. Sadly, such claims have done much to damage the field of AI. He says: The intellectual dishonesty in the presentation of the Wolfram Language, whether intentional or unintentional, disturbs me, as I’m sure it does many other computer science professionals. He also calls it rehashed snake oil.

    Current Mood: amused
    Wednesday, February 26th, 2014
    11:21 am
    Sorry, I know it's been a while
    I'm terribly sorry that I haven't written anything in here since October, but I've been awfully busy with work, life (including the insanity leading up to Further Confusion), and illness, in no particular order.

    I feel especially bad since I promised someone at the fursuit parade (at FC in January) that I'd post photos of the parade here on this account, since I have taken many and this particular gentlefox was nice enough to set up a pose for me twice. (The first shot was crap. Not fast enough on the shutter release!)

    Of course, it didn't help that I was sick during the entirety of Further Confusion, and for a couple weeks afterward. But that's just an excuse for procrastination.

    Current Mood: working
    Thursday, October 17th, 2013
    4:52 pm
    Another reason why I want to throttle the jqGrid developers
    I had a vexing problem today which boiled down to a Javascript array being modified behind the scenes by jqGrid.

    Say you have a jqGrid and you want to operate on all the rows that are selected (assuming you've got it set up for multiselect). In fact, my code was doing this in order to bulk move items from one grid to another, but the important fact is that the items were being deleted from the source grid piecemeal.

    To obtain the array of selected rows, you would use something like:
    var rowids = $('#foo').jqGrid('getGridParam', 'selarrrow');

    This gives you an array that you can iterate over to operate on those selected rows. But what I noticed is that all but the last row seemed to be processed; further investigation showed that it was actually roughly half of the rows selected. Even worse, the $.each utility function from jQuery was feeding 'undefined' values to the callback function. Say what?

    Yep, it turns out that jqGrid doesn't hand you back an array you can just do with as you please. No, it actually hands you a reference to its own internal array which tracks these things. So as you delete items one by one from the grid, the array you're iterating over is shrinking, and your index will eventually point to nonexistent values.

    The solution? Well, you can copy an array using Array.prototype.concat(), which looks clunky but seems to work. I'm not sure if there's a better way out there that works across all major browsers.

    But really, I don't think anyone should have to do something like this with a robust UI widget.

    Current Mood: nerdy
    Thursday, September 12th, 2013
    4:27 pm
    Is English a Pidgin Language?
    Today, a coworker of mine opined (rather forcefully) that English was a pidgin language. When pressed, he mentioned something about English being used in trade (true enough), and that English incorporates bits of other languages (also true). However, neither of these things makes English a pidgin by themselves. Yet the idea that English is a pidgin language persists, so much so that Google cheerfully suggests search strings like is english a pidgin language when you start typing in such a query.

    You'd think that, with such a common query, there would be more relevant results, but there really aren't. I managed to find this discussion which started out as a discussion of the grammar of non-English dialects of England, Cumbria in this case. One of the participants says it thusly:
    Nor is English a pidgin language — Modern English is derived via Middle English from Old English (Anglo-Saxon). It has been influenced by Old Norse — hardly surprising considering the political sway held by Scandinavians in Britain at one time and the more or less mutual intelligibility of the Old Norse and Old English languages. English vocabulary does borrow heavily from other languages but that is not unusual. Most of the basic ordinary words that are used in English can in fact be traced back to Anglo-Saxon.
    By the way, the thread is also archived here. The many auxiliary verbs in English seem to be a Norse/Viking borrowing; even German doesn't have an auxiliary for infinitive forms, whereas English does (e.g., “to be,” where to is the auxiliary).

    This seems to suggest that a language can't be a pidgin if it has a provenance, or a pedigree of some kind. But there are many forms of pidgin which have been around for centuries, long branched from their source languages, so that can't be the sole determining factor.

    So what is the definition of pidgin? The dictionary says this:
    an auxiliary language that has come into existence through the attempts by the speakers of two different languages to communicate and that is primarily a simplified form of one of the languages, with a reduced vocabulary and grammatical structure and considerable variation in pronunciation.
    An alternate definition adds:
    Unlike creoles, pidgins do not constitute the mother tongue of any speech community

    OK, now we're getting warmer. So as the official language of England and the primary language spoken throughout the UK, English would probably not be considered a pidgin.

    The Wikipedia entry largely reiterates these points, but also lists common traits of pidgin languages, none of which mainstream English possesses.

    What about potential flies in the ointment? If a pidgin is not the primary spoken language for a language group or speech community, and if a pidgin is typically learned as a second language (as the Wikipedia article suggests), what do we make of cases where Pidgin English (a pidgin form of English) is considered an official language of a country, e.g. Papua New Guinea? Even if it's an officially recognized language, it seems that Pidgin English is never the primary language of the country. (I'd be interested if someone comes up with a counterexample where any pidgin, regardless of source language, is the primary or only form of language in a given region. Would that magically make it a creole instead?)

    Another question is whether you can generate a pidgin language from a pidgin language. If English is a pidgin language, what does that make Pidgin English?

    So, what do you think? Are there any (preferably online) sources that actually answer the question definitively? If so, please share! I'd like to be able to speak authoritatively when this topic comes up again.

    Current Mood: curious
    Thursday, August 15th, 2013
    4:03 pm
    Tough times for a grammar Nazi
    For the record, I really despise the term “grammar Nazi” for several reasons, not the least of which is the gratuitous comparisons to a group of people responsible for some of the worst human rights violations of the 20th Century.

    That said, I was saddened to discover that many dictionaries are now including a new definition of literally. Specifically, this is the common (mis)use of the word as an intensifier that is almost the exact opposite meaning of the literal and, many would say, correct meaning. At least only puts the “new” sense of the word in a usage note.

    Current Mood: sick
    Thursday, July 18th, 2013
    3:13 am
    Perhaps the best cheap ultrabook for coding
    So you want a thin, ultraportable computer for doing a bit of creative writing or a bit of noodling with some code, but you don't want to spring for a MacBook Air? Sure, there are some options out there that will work nicely.

    I'd dearly love to get my hands on a Samsung Series 9, but the cheapest I've seen is still very close to what you'd pay for a low-end MacBook Air. Newegg and Amazon do have pretty regular deals, and it was Amazon that happened to have the deal that worked the best for me. There were plenty of relatively cheap options, but this article at Coding Horror convinced me to give the ASUS Zenbook series a closer look.

    Since the goal was a cheap ultrabook that I could realistically code on, I didn't need the 1080p resolution or the pure SSD of the model reviewed in the aforementioned article. The other thing I could do without is Windows 8 — given the choice, I'd rather have Windows 7 preinstalled than have to nuke the preinstalled OS and waste a license. Dual-booting seems like the best option for maximum utility.

    So I picked up an older Zenbook model with a 2nd generation Core i3 processor, the UX32A-DB31. The vendor that Amazon sourced it from, PENS, is geographically very close, so it arrived quickly even with Super Saver shipping. The price seems to have dropped a little bit since my order, so get 'em while they're hot. Comparable models shouldn't cost too much more.

    I also ordered some extra memory, since the system only comes with 4 GB of RAM. Sadly, 2 GB are soldered directly to the motherboard, so you can only replace a single stick. I picked up an 8 GB stick of Corsair Vengeance performance RAM. Installation required a Torx T5 bit, acquired on the cheap at the local discount tool store. If you do this, be sure to keep a little cup handy for the 12 screws you'll need to put back when you're done. Replacing the RAM is a simple but tedious procedure. I wound up not transferring the heat spreader from the old SODIMM because the new RAM already had heat spreaders preinstalled. Windows Experience sub-score for memory jumped from 5.8 to 7.2 — and more importantly, things feel subjectively faster. The OCD part of me feels a little strange about having 10 GB of RAM, though, since it isn't a power-of-2.

    Since there's no built-in ethernet port, I picked up these accessories (although it turns out the ultrabook comes with a micro-VGA adapter already, so now there's a spare).

    I'm still setting things up, but I've already got Ubuntu 13.04 installed as a secondary OS, with developer tools installed on both operating systems. Netbeans, IntelliJ community edition, MIT Scheme, etc. Sadly, the Ubuntu packages for Grails that I mentioned in a previous post don't seem to work well on the latest release, so it appears a completely manual install is required.

    Current Mood: pleased
    Wednesday, July 10th, 2013
    11:26 am
    Grails stuff that pleases me greatly
    Now that I'm getting to work with more recent versions of Grails, I've been investigating a few things to make my life easier down the road.

    First off, it turns out that there are some great Ubuntu packages for Grails which obviate much of the annoyance of setting it up and working with it. (They even have a package to provide bash completions for the Grails commands.) Since I'm going to be setting up an Ultrabook soon, I planned on dual-booting Linux; this makes me want to use Ubuntu rather than, say, Linux Mint.

    I also finally noticed the new Pivotal initiative that the Spring and Grails communities are part of. While reading up on what this means to me as a Grails developer, I saw the following:
    Grails 3.0 will separate Grails from the traditional application server and extend Grails’ reach to allow for the development of lightweight, asynchronous applications. Grails’ persistence technology GORM has also been evolving beyond the traditional relational database, with implementations for NoSQL databases now available. GORM will continue to be an important technology for us as enterprise data fabrics evolve.

    I'm pleased to see this, because NoSQL data stores are becoming more important (despite some disillusionment in certain quarters), and while JDBC provides a good-to-excellent abstraction for relational databases, it can't really be adapted to non-relational data stores. It's also pretty heavily tied to SQL and SQL datatypes. GORM provides a much higher level of abstraction. I do wonder, though, if they'll rename GORM since it will abstract both relational and non-relational data — it wouldn't be the Grails Object Relational Model anymore.

    I imagine a lot of admins are going to push back on Grails 3.0 deployments just because they are familiar with their existing app servers like Tomcat, JBoss, etc. (Some folks at Apollo Group didn't like deploying Mule as a stand-alone ESB instead of a WAR inside a JBoss instance, for instance. Lack of familiarity breeds distrust, though I suspect lack of technical acumen on the part of their production deployment team played a role.)

    Current Mood: excited
    Sunday, June 30th, 2013
    7:09 pm
    Yay! New router firmware!
    I installed the latest firmware for my Asus RT-N56U, and all seems to be going mostly well. The thing seems generally snappier, the web-based UI is much more refined, and long-running TCP connections don't seem to be choking/seizing/timing out on me.

    Took me a while to get it talking to my computers again last night because this firmware update required resetting the router to factory defaults (one of the reasons I didn't want to make the switch to the new 3-series firmware). The promise of functional IPv6 was enough to win me over, and I knew having bittorrent capabilities built into the router that no longer required a Windows client application to use would sweeten the deal.

    Well, the UI improvements and performance improvements make me pretty happy, but I'm not terribly excited about IPv6 so far — because it's not working. Oh, I've got the router assigning IPv6 addresses via DHCP, but I am not sure if I have it talking to the Qwest Q1000 modem correctly. So far, I am using 6rd tunneling, which seems to get me results that other options on the router don't. I did enable IPv6 on the Qwest modem per the instructions at this page.

    Anyone have any ideas to get my router properly talking IPv6 to the Q1000?

    Current Mood: accomplished
    Thursday, February 14th, 2013
    5:37 pm
    Finally getting non-Gmail e-mail accounts to sync on the HTC One X+
    Having recently upgraded from the HTC Inspire 4G to the HTC One X+, I have noticed two annoying things:
    • The bluetooth seems to over-amplify the voice of the person I'm calling, if I'm the one originating the call. (It seems to do the same thing when I'm receiving the call, but that's a more rare case so I'm not as certain of it.) Reports around the 'net indicate that this is a known issue, and will probably be addressed by a Jelly Bean update (whenever AT&T gets around to passing that along) and/or an HTC update. Apparently, the gain is getting set higher than it should, causing clipping and distortion. The problem isn't the showstopper that some folks make it out to be, though, so I'm not returning the phone. This was tested with my Nissan Juke.
    • The Mail app (not the Gmail-specific app, but the other one that ships on this phone — not sure if this is a Jelly Bean app or something HTC developed) wasn't syncing, so I only found out if there were new messages when I manually launched the app.

    It turns out that the second item was something I could fix. The trick is to not set up or edit your e-mail account details from within the Mail app. Instead, you need to go into the Android Settings app, drill down into Accounts & Sync, and add an account specific to that app. Almost every setting is available from here, and what's more, this ensures that you get the sync behavior you expect, with mail being checked at your requested interval. Resist the temptation to use the settings from within Mail, or Mail (and the account you just set up with it) will suddenly disappear from the list of accounts to sync as shown in Android Settings.

    Current Mood: accomplished
    5:20 pm
    Hot Topic finally responds
    I finally received an e-mail from Hot Topic regarding the problems I'd had with the Deluxe Edition of In This Moment's album, Blood. As I recently wrote, there was supposed to be a bonus track on disc 1, specifically a cover of the Nine Inch Nails song “Closer.” (I had even thought that perhaps the bonus track was simply appended to the last track after a silent gap, but no dice... that track is too short to contain two songs.)

    Hot Topic finally responded, saying that there was indeed a mistake made:
    Thank you for emialing us at! I am so very sorry but this is what we recieved from the band


    Sadly the bonus track of the NIN cover of "Closer" was left off our Hot Topic Deluxe Version of "Blood"
    To fix this, we've setup a special site you can go and download the track at.
    Please go to the link below to download the tack.


    or you can send an email to BLOOD@CENTURYMEDIA.COM with your mailing address and we will mail you out a CD single of "Closer".

    Well, I already spent money for the bonus track on iTunes (which they indeed did include in their version of the Deluxe Edition — so much for Hot Topic exclusivity), so I don't need to grab this, but someone else might find this useful.

    Current Mood: disappointed
    Sunday, February 3rd, 2013
    12:50 pm
    Ripped off!
    So I've been listening to In This Moment a lot lately on XM's Octane channel, and liked their music enough that when I saw the exclusive deluxe edition of Blood on sale at Hot Topic, I decided to pick it up. (Krissy had some coupons that were about to expire anyway, so it seemed like a good time to use 'em.) One of the advertised benefits of the deluxe edition is the inclusion of a second bonus disc, as well as a cover of the Nine Inch Nails song “Closer.”

    Now, the wrapper on the product as sold at Hot Topic had a sticker proclaiming this, and the sleeve around the jewel case also clearly states that track 15 on the album is the bonus track, “Closer.” The band's official website also clearly states that this song is included in the deluxe edition, exclusively available through Hot Topic. So you would think that there would be no confusion that buying this deluxe edition of Blood would result in obtaining this sought-after track...

    But no, if you remove the CD jewel case from the sleeve, you see that the track listing on the jewel case insert only lists 14 tracks. The bonus CD is there, but it only has the promised 4 tracks, none of which is “Closer.” Confusingly, some press outlets such as Loudwire and Brave Words & Bloody Knuckles mention this bonus track as being on disc 2. It isn't.

    I'll tell you where it is, though. On iTunes… for an additional $1.29. Oddly enough, it wasn't until I tried to rip the two CDs that I discovered the rip-off. Maybe this is an oversight, but shockingly I have seen no complaints about this anywhere on the Web.

    Current Mood: aggravated
    Thursday, December 6th, 2012
    2:56 pm
    Hubris or not?
    Here's a video of Neil deGrasse Tyson getting a bit silly (some say “philosophical”) with Jason Silva:

    What I find interesting here is that Jason quotes Carl Sagan from Cosmos: “We are a way for the universe to understand itself.” Tyson then chastizes Silva by saying this is hubris, because we understand the universe very badly, and we're not very smart, and we don't have very good senses.

    But is this really a valid criticism? It seems to me that Sagan meant or intended that understanding was a process, not a static state, and our understanding is growing all the time. Sagan was also optimistic that humans would continue improving themselves and the tools they use to understand the universe. It almost seems that Dr. Tyson either doesn't think this is going to happen (whether because we'll destroy ourselves or get wiped out by a disaster, or simply because we stagnate biologically and intellectually), or else he isn't willing to take the long view because humanity's future priorities are unknowable. It's really hard to say.

    I find this interesting because Carl Sagan was one of Dr. Tyson's mentors, and because Dr. Tyson is now working on a sequel/reboot of Cosmos with Seth MacFarlane... to be broadcast on FOX. Yes, you read that right. It's either the most brilliant move in history, to try and enlighten those who need it the most (since the PBS crowd is already pretty well educated), or it's a hugely bone-headed move and FOX will cancel it after 2 or 3 episodes.

    Frankly, the populist slant worries me. When Neil deGrasse Tyson did a miniseries for NOVA a few years ago, it was very dramatic and spectacular (especially visually), and Tyson had a lot of gee-whiz enthusiasm for the subject matter, but the miniseries felt quite light on exposition. It felt light on science. So I wonder what the tone of this new Cosmos is going to be, and if it will dumb down some of the harder stuff just to try and reach more people. The fact that they're already touting the cutting-edge special effects has got me on high alert.

    So, is Dr. Tyson right? Is Sagan's quote hubristic? Is Tyson repudiating Sagan? Are humans really a way for the universe to understand itself, at least a little?

    Current Mood: confused
    Wednesday, December 5th, 2012
    5:23 pm
    Groovy's "use" keyword, Categories, and computing time
    Groovy has some really nice facilities for creating syntactic sugar, beyond what the language already provides — this is part of what makes it so trivial to create domain-specific languages (DSLs) in Groovy. One means of doing this is the so-called “Pimp my Library Pattern.”

    If you check out the link above, you'll see an example of how to create a Category, which is essentially implemented as a class with some static methods that you want to decorate onto certain classes of object inside the use block. The first parameter of the method represents the class being extended; within the use block, any object of that type (or related type) can have the method invoked upon it.

    So, if we have a Category method of the form:
    static Integer sum(Integer self, listOfInts) { listOfInts.inject(self, {acc, val -> acc += val}) }
    ...then we can invoke this inside a use block as follows:
    4.sum([5, 6, 7])
    ...which evaluates to 22. Note how the primitive literal 4 is treated as an Integer by Groovy. Incidentally, the closure used with inject can be simplified, and the static method could be rewritten as:
    static Integer sum(Integer self, listOfInts) { listOfInts.sum(self) }

    This might not seem terribly powerful at first, but you can see some sophisticated examples if you spelunk into the already supplied TimeCategory in Groovy. With TimeCategory, you can write expressions such as 10.hours.ago or, or you can do things like someDate - 14.days (or, equivalently, someDate - 2.weeks) where someDate is an instance of java.util.Date or one of its subclasses. This is powerful, and aids in readability and code comprehension, not to mention simplifies the writing of code.

    Current Mood: nerdy
    Tuesday, December 4th, 2012
    5:16 pm
    Java enums and switch statements in Groovy
    I'm a big fan of enumerations in Java — in this case, I'm talking about Java's answer to C's enum construct, which also uses the enum keyword. I'm emphatically not talking about the java.util.Enumeration interface, which has more-or-less been replaced with java.util.Iterator.

    One thing you can do in Java code is something like the following:
    import foo.MyEnum;

    public class DoesSomething {
    public void doLogic(MyEnum val) {
    switch (val) {
    case AA:
    // some logic here...
    case BB:
    // more logic...
    default: break;

    Then the corresponding enum would be declared separately as something like this:
    public enum MyEnum { AA, BB, CC }

    Notice how Java allows you to use the values from MyEnum for each case statement. Unfortunately, Groovy is different. It turns out that you can't write code like the above without explicitly providing the enum classname:
    import foo.MyEnum

    // The Groovy way:
    class DoesSomething {
    public void doLogic(MyEnum val) {
    switch (val) {
    case MyEnum.AA:
    // some logic here...
    case MyEnum.BB:
    // more logic...

    So, that's kind of annoying, although this is one of the prices you pay for a very dynamic language. On the other hand, you can take any arbitrary String value in Groovy and convert it into an enum type easily in Groovy:
    def q = "CC" as MyEnum // q now contains MyEnum.CC

    You can similarly convert strings into numerics (and vice versa) using the as Groovy keyword, which is great when developing web apps in the Grails framework.

    Current Mood: nerdy
    Thursday, November 29th, 2012
    10:54 am
    Revisiting classes where compareTo() is inconsistent with equals()
    I had previously written an article about Java's Set, and how it misbehaves with elements for which compareTo() and equals() are inconsistent. Today, I discovered that this type of inconsistency has other knock-on effects in dynamic JVM languages.

    Specifically, I'm talking about the Groovy programming language. Since my new job requires writing code in Groovy, I've been re-learning a bunch of things I'd previously picked up in classes taught by, and conference presentations given by, No Fluff Just Stuff, and Scott Davis in particular. While Groovy is a great language, and is the foundation of the Grails framework, it does have some rough edges.

    Here's an article from 2010 about one such idiosyncrasy of Groovy. To start with, Groovy redefines == so that, when objects are being compared, equals() is being called under the hood; if you want to compare object identity, you use the is operator instead. So far, so good. But it turns out that == has an additional wrinkle — when the objects being compared implement the Comparable interface, compareTo() == 0 is used instead of equals().

    There may be legitimate reasons to create classes with inconsistent behaviors for these two methods, such as BigDecimal — note however that in the case of Groovy, BigDecimal is wrapped, and all mathematical operators overloaded for this case. In fact, all floating point constants in Groovy code are by default treated as BigDecimal and not as double or float. (This is one reason that Groovy and Grails are so popular with insurance companies, since BigDecimal isn't susceptible to the same cumulative errors and inexact representation problems that the primitive floating point types have.) Just be aware that, if you must create such a class, tread carefully.

    Current Mood: surprised
    Wednesday, November 14th, 2012
    5:28 pm
    Idiosyncrasies setting up svn+ssh
    I could have sworn I had to set up a connection to an SVN repository via an SSH tunnel, but either I had totally forgotten how, or else I was completely mistaken. Or the procedure has changed entirely...

    That said, I can now see why a bunch of code shops keep their own SVN server with simple authentication/authorization and avoid the use of SSH tunneling. It's just way more complex than it needs to be, at least on Windows.

    I already knew that if you want to use various newer spins of Eclipse with SVN in a 64-bit Windows environment (especially if using a 64-bit JDK), you need to use version 1.8.x of Subclipse or later; prior versions will give you JavaHL errors. In this case, though, it made more sense to use SVNKit even after installing Subclipse 1.8, and once repository permissions were fixed, this worked great. (Springsource Tool Suite and its various spins still default to Subclipse 1.6, so be sure to add the Subclipse 1.8 update site to the list of available sites in the Help→Install dialog, and then install from that site. See this page for the URLs to the various locations for different Subclipse builds.)

    Note that if you used PuTTYgen to generate public/private secure keys for SSH tunneling, you'll need to convert the PuTTY-formatted private key into OpenSSH format, which is preferred by Subclipse. The other key to getting Subclipse to play nicely in Eclipse or STS is to navigate to Window→Team→SVN and in the drop-down menu labeled SVN interface set the client interface to SVNKit (pure Java, i.e., does not use JNI).

    Some advice will tell you to set the SVN_SSH environment variable combined with JavaHL instead, but I found that doing so caused me more headaches than anything else. I would not recommend relying on this method. Both Eclipse and Tortoise have their own ways to configure the SVN client specified by SVN_SSH, anyway.

    I already talked about configuring the SSH tunnel in Eclipse and derivatives above, so what about TortoiseSVN? There are many blog entries and articles that attempt to address this issue, but the cleanest and clearest set of instructions I found were at this wiki page for the Mono project. The crucial setting is in TortoiseSVN settings (obtained by using the contextual menu in any explorer window, then navigating to the Network node in the tree at the left-hand side of the dialog). There's a text box here which must contain the full path to the SSH client binary. Since TortoisePlink.exe is a Tortoise-specific version of the PuTTY plink.exe, and since PuTTY is distributed mainly as a 32-bit binary whereas I installed the 64-bit version of TortoiseSVN, this was the right choice for me (and probably most other users as well).

    Note that TortoiseSVN also provides access to a Subversion configuration file (under the General node in the settings dialog). Even though this config file contains a setting that ostensibly points to the SVN client (and references the SVN_SSH environment variable mentioned earlier), the TortoiseSVN UI seems to completely ignore this setting. This was the source of much confusion. Presumably, the command line tools which are an optional install with Tortoise will honor this particular config setting in the Subversion config file. Just don't bank on it.

    Of course, it chafes me to have to run pageant to cache keys, but it beats having to type my passphrase repeatedly to decrypt my key for authentication. The other big gripe with TortoiseSVN is that, using svn+ssh, if you don't include your user ID in the repository URL (e.g., svn+ssh:// or otherwise pass your user ID to/through plink somehow, you'll be prompted for your user ID or other credentials every single time Tortoise walks to another node in the directory tree.

    Here are some other useful links dealing with this very issue:

    Current Mood: accomplished
    Tuesday, October 30th, 2012
    10:43 pm
    Static classes in Java?
    Today, I had a job interview in which I was asked what a static class was, and how it differs from a singleton. This caught me off guard, mainly because I've never heard other Java developers refer to “static classes,” but rather utility classes. To me, that's a class that is not instantiable (typically enforced by having a private constructor, which either has nothing in the body or else throws some kind of RuntimeException) and which has all static methods. A canonical example would be java.lang.Math.

    Something nagged at me about this, so I did a bit of Googling when I got home. Sure enough, there was a good reason for my nagging feeling. Technically speaking, you can't have a top-level class in Java that's declared static — you can only declare an inner class, also known as a nested class, to be static. Doing so makes the inner class unable to see members of the enclosing class, and so it's no different in practice from an outer or top-level class. Contrary to what you might expect, you can create a new instance of a static inner class. As for why you might want to use a static inner class versus a top-level class, that's a structural design choice. I know I've never had occasion to declare a static nested class.

    So if Java doesn't exactly support the syntax of a top-level static class, even though it supports the semantics of such a beast, why call it a static class? It seems that other languages like C# do allow you to declare a top-level class as static, and this has the effect of making the class abstract final; in Java, a class can be abstract or final, but not both. I'm guessing that the growing popularity of .Net languages like C# is having an effect on the terminology of JVM language developers. And while the singleton is a recognized design pattern, I am not sure I have ever heard of a static class design pattern. (Technically speaking, a non-instantiable class with nothing but static methods is just a collection of functions, and doesn't fit neatly into Object Oriented methodology. The class is nothing but a way to group together functions that may or may not actually be related.)

    In fact, one could probably argue that a static class, in the sense of a non-instantiable top-level class with static methods, is in fact a kind of singleton. You simply can't have serializable state information in such a class. (Only a class instance can be serialized.)

    It's worth noting that, as of Java 5, you can statically import individual methods from a class, further emphasizing the non-OO-ness of these methods and where they reside:
    import static java.lang.Math.abs;

    This article discusses the static class idiom in Java, and this article discusses when and how you may use classes actually declared as static in Java. Here is another good article on the topic of Java and static class declarations, though I find some of the terminology to be a bit odd.

    On the topic of singletons vs. static classes, I found this article to be pretty useful. The author points out one advantage of singleton classes that I don't often consider: You can subclass a singleton class to override its behavior in a meaningful way.

    Current Mood: restless
[ << Previous 20 ]