#clojure logs

2010-07-06

00:00cais2002there is ubuntu in my computer and the deployment is ubuntu, too.. just that win is still my main platform for other daily activities and I some time seem to like to torture myself just to test the true protability of java..
00:02Blackfootcais2002: ctrl+u kills to the beginning of a line, again not sure if it works in windows though
00:03itistodayBlackfoot: didn't know that, thanks for mentioning it
00:04technomancyctrl-u is the prefix arg; it's not actually a command.
00:04itistodaytechnomancy: that's in emacs though
00:04cais2002Blackfoot, neither.. anyway, I decide to do ENTER + ^Z + ENTER to clear a partial line..
00:04itistodaythis is for the terminal
00:04technomancyoh, duh.
00:05cais2002but thanks for the ^u tip..
00:05technomancylike an rlwrap thing, then?
00:05itistodaytechnomancy: yeah
00:05itistodaytechnomancy: btw, i think i figured out what with-local-vars is for
00:05itistodaytechnomancy: so with (binding [a b] .. ) you can use set! to set a
00:06itistodaybut you can't do that if 'a' isn't defined beforehand as a var
00:06itistodayso if you want to perform local mutable setting
00:06itistodayyou'd use with-local-vars if you weren't manipulating an existing var
00:07technomancyoh sure... that would be another difference between the two
00:07technomancystill not sure if there's any good reason to set locals to begin with though
00:08itistodaywhy not?
00:08itistodayit could be useful for performance
00:08technomancytheoretically possible, but I think transients probably cover that better
00:09itistodayyeah i see it exactly in the domain of transients, but those can only be used on collections
00:09itistodayi'm guessing though that with recur/loop/reduce it's probably a rare situation where you'd need with-local-vars though
00:10technomancyright, but if it happens over and over again (enough to make a difference for perf), it is probably going to involve a collection.
00:11itistodayindeed... i'm glad though that it's there as an option, albeit unlikely ever to be necessary
00:11itistoday(and to know what it's for)
00:17Blackfootis there an opposite of (dissoc) that only keeps the given keys
00:18tomojnot quite
00:18tomojbut there's select-keys
00:18tomoj,(select-keys {:foo 3 :bar 4 :baz 5} [:foo :baz])
00:18clojurebot{:baz 5, :foo 3}
00:19Blackfootyes that is perfect thanks
00:19arohnerin a maven multi-module project, is there a magic command to bump all of the version numbers?
00:20itistodayarohner: if no one answers here there's also a #maven channel
00:20arohneritistoday: oh right, thanks
00:20tomojmaybe maven-release-plugin has something?
00:21tomojoh it says you will be prompted for the version number for each module
00:21tomojunless submodules always have the same version as the parent
00:21tomojhttp://maven.apache.org/plugins/maven-release-plugin/examples/prepare-release.html
00:25arohnertomoj: thanks
00:26BahmanHi all!
00:29arohnerBahman: hi
00:40itistodaywhat are some functions for finding a symbol in a list?
00:40itistoday(its index, or replacing it with another symbol)
00:41tomoj,(replace '{bar baz} '(foo bar))
00:41clojurebot(foo baz)
00:42itistodaytomoj: thanks, any others like it? perhaps something in contrib?
00:43technomancyitistoday: there's (some #{2} [1 2 3])
00:44itistodaywhat about pattern matching type stuff?
00:44technomancy(one of the few places Clojure inherits from CL's heritage of poor naming to its detriment)
01:07BahmanAre there any MongoDB connectors other than CongoMongo?
01:07BahmanLast activity in CongoMongo dates back to Feb. Wondering if it's sort of inactive?
01:11mudgechouser: awesome, thanks, and thanks
01:12mudgeitistoday, I don't get it, what is ICH BIN EIN NERD ?
01:13itistodaymudge: see the 2nd youtube link, it has more context: http://www.youtube.com/watch?v=3C4PqyH6Ga4
01:13itistodayjust a quote from a show
01:13itistodaya funny basterdization of the kennedy speech in berlin
01:13itistodaygotta run (literally)
01:15mudgeokay, it is funny
01:17BahmanSorry got DC. Any ideas regarding the MongoDB question?
01:32mudgehey, what's your guy's favorite clojure book?
01:34RaynesThe Joy of Clojure is awesome.
01:35mudgecool, what makes it awesome?
01:37RaynesIt's very detailed, for one. The book teaches me things I need to know that aren't even directly related to Clojure, such as with the brief introduction to big o notation.
01:38mudgecool
01:41SandGorgonhi guys.. first time clojure user here. I'm starting out with bcarper's cown-blog (http://github.com/briancarper/cow-blog) . I dont understand the meaning of "Look at (and run) blog.db.postgres.clj/init-db-postgres to create the tables in your database." how do I run that method ?
01:44fuchsdIs there a good discussion somewhere of when to use def vs when to use let?
01:55vu3rddRaynes: hope you got a link to the pdf
01:55Raynesvu3rdd: I gave up. I can't figure out what email I signed up with to get into the account section.
01:55Raynes:p
01:55RaynesI'll work on it later.
01:56vu3rddRaynes: Oh.. ok.
02:32SandGorgonwhy does leiningen need to pull in JARS from clojars ? why cant it pull clojure source code and put in the appropriate location in my file structure. Bundling clj libraries as jars makes sense if you have a non-free libary, but for most of the stuff out there, it should be pure clojure all the way down
02:33SandGorgonI can also understand it for deployment - not for development
02:35tomojclojure's source code is in the jars..
02:36tomojexploding the jar and dropping core.clj and friends into your project would be crazy
02:36tomojand anyway much of clojure is java
02:42SandGorgontomoj, why would it be crazy ? most of ruby gems are exploded as ruby code .. would it not be very helpful if you are debugging or so ?
02:44RaynesIt's cleaner to keep them packaged as jars. The source code is in there, so why pull it out and clutter everything up?
02:44RaynesI don't see how it would be helpful for debugging.
02:46SandGorgonRaynes, I understand what you mean, but it could simply be stored as separate directories in the "lib" subdirectory of a project - just like each jar dependency is a separate file. it would be no more cluttered that it already is.
02:46RaynesBut *why* would you want this?
02:47tomojit wouldn't be helpful at all to me for debugging
02:47SandGorgonRaynes, the issue is if you figure out that you need to bugfix one of the dependency you are using - it would be easier if all of them were in clj format .. we have had issues where we saw we could simply modify our GEM dependencies and get on with life
02:48tomojthat doesn't work
02:48SandGorgondeployment ,of course, would be as a jar
02:48tomojunless you store all your dependencies in your source repo
02:48RaynesThat would kill the point of dependency management.
02:51SandGorgontomoj, i'm not sure i understand... lein pulls in all dependencies in your CURRENT project directory. another similar project - liebke/cljr pulls in dependencies in a shared folder in your home directory. That would mean you no longer store your dependencies in your source repo. Besides I'm not asking for storing dependencies in the repo... just that they be be pulledin and managed as source
02:52SandGorgonnote that my thought is only for those jars that are written as clojure .. not java-written jars
02:58ChousukeSandGorgon: handling source would require a lot of code I think
03:00Chousukethough if there's a maven plugin, maybe not.
03:00zmilai don't want to bother with source code of the libs i use. just have jars.
03:04bortrebif you change the source code for a library you use, then you no longer depend on that library -- you depend on your own special version of that library. That source should then be kept under your own version control, etc, and would not rightly be part of a dependency manager like leinengen.
03:05bortrebso while there's nothing stopping you from exploding a jar and dealing with the source in that way, why should it be an option for leinengen?
03:13tomojSandGorgon: so you want leiningen to download the source files for clojure exploded into some directory and have multiple individual projects refer to this source?
03:16SandGorgontomoj, I am not really focusing on single vs multiple directories - just that having clj source zipped up and calling it a JAR file seems to be hold-up of the J2EE era. I just really hope that if my project has a dependency which a clojure project, then it is pulled in, used and maintained as such. that's all
03:17tomojit basically is
03:17tomojthe jars lein creates have their project.cljs for instance
03:18tomojwhy does it matter whether it's stored on disk in a jar or exploded?
03:18tomojas it happens the jar format is incredibly convenient
03:23tomojit is practically convenient to respect our host :)
03:27cais2002,(defn f [x] x+1)
03:27clojurebotDENIED
03:27cais2002,(def f 1)
03:27clojurebotDENIED
03:27replacacais2002: clojurebot doesn't allow def
03:28mudgewhy not
03:28cais2002yeah, seems so
03:28cais2002any idea who wrote clojurebot?
03:28replacacais2002: hiredman
03:29replacamudge: it's a secure sandbox
03:29cais2002is it an ad-hoc sandbox or something built-in from clj?
03:30Raynesmudge: If you def things, those things are kept in memory. Eventually, you run out of memory.
03:30mudgeneat
03:30replacacais2002: he found some java sandbox code somewhere and adapted/wrapped it.
03:31mudgereplaca: why not just give clojurebot a memory limit? so then it can def things without taking too much memory
03:31cais2002nice
03:31Raynesmudge: Because it isn't that simple.
03:31Raynescais2002: http://github.com/hiredman/clojurebot/blob/master/src/hiredman/sandbox.clj
03:31replacamudge: question for hiredman. I haven't thought about the ramifications of def.
03:32mudgeokay
03:32Raynessexpbot is another bot (mine) that does sandboxed Clojure evaluation. It uses clj-sandbox, Licenser's more generalized Clojure sandboxing library.
03:32Raynes$google clj-sandbox
03:32sexpbotFirst out of 133 results is: Licenser's clj-sandbox at master - GitHub
03:32LicenserSomeone said my name?
03:32sexpbothttp://github.com/Licenser/clj-sandbox
03:32replacamudge: but it's java. It already has a memory limit.
03:33LicenserJava has no simple way to limit memory aside from for the entire process
03:33RaynesOn Licenser and I's http://try-clojure.org site, we use clj-sandbox like sexpbot does. Licenser added some hackery to allow def, so you might want to ask him about that stuff.
03:35cais2002Raynes, thanks for the info
03:36Licensermudge: to explain, yes it would be possible to give the bots a meory limit, and both have. But this would only protect the server behind the bot not the bot itself. It would still be possible to make it un responsive by filling it's memory
03:36mudgeyea
03:36Licenserand neither java nor clojure give you a real way to calculate memory usage
03:36mudgehmmm
03:37Licensermudge: if I am wrong please please tell me how it works :P but sadly I'm rarely wrong
03:37mudgewell that's good
03:37mudgemaybe clojurebot could automatically be restarted every once in awhile
03:37RaynesThat would be tedious and not worth the effort for both bots.
03:38RaynesIt still wouldn't solve the problem.
03:38Licensermudge: no good solution
03:38RaynesYou'd have to restart every 30 seconds, :p
03:38Licenserand that would anihilate the gain of having def since after a restart itd be gone anyway ;)
03:38mudgebut having the bot being able to def things is such awesome capability for a bot, maybe give a little or put some effort into a solution
03:39RaynesI don't think it's important.
03:39RaynesYou can always use let or letfn.
03:39mudgesure, its not important, just fun
03:42mudgeoh yea, let is good stuff
03:49cais2002,(eval '(+ 1 2))
03:49clojurebotDENIED
03:51Lajla,(+)
03:51clojurebot0
03:51Lajla,car
03:51clojurebotjava.lang.Exception: Unable to resolve symbol: car in this context
03:51Lajla,(car 1)
03:51clojurebotjava.lang.Exception: Unable to resolve symbol: car in this context
03:51LajlaNo volkswagens?
03:51Lajla$(car 1)
03:51sexpbotjava.lang.Exception: Unable to resolve symbol: car in this context
03:52_2x2ltheres no car or cdr in clojure
03:52_2x2luse first, rest
03:52mudge, (+ 5 6)
03:52clojurebot11
03:52mudgethat was fun
04:11LauJensenMorning guys
04:13BahmanHello LauJensen!
04:13mudgemorning!
04:18esjMorning gentlemen.
04:18mudgemorning esj
04:18mudge(morning clojurebot)
04:19mudge,(morning clojurebot)
04:19clojurebotjava.lang.Exception: Unable to resolve symbol: morning in this context
04:19mudgehmm... that should be rectified
04:21esj,morning
04:21clojurebotjava.lang.Exception: Unable to resolve symbol: morning in this context
04:21esj$morning
04:21sexpbotCommand not found. No entiendo lo que estás diciendo.
04:22esjRaynes: feel like teaching your bot some manners :P
04:23zmila(def morning :morning)
04:23zmila,(def morning :morning)
04:23clojurebotDENIED
04:23esjnow its just being rude !
04:31Raynesesj: He's a sexpbot, not a mannerbot. ;p
04:31esjin my day, manners were very sexp
04:31RaynesGet on my lawn.
04:31esjkidbots these days
04:32RaynesAdultbots just don't understna.d
04:32Raynesunderstand.*
04:33mudgehaha
04:35mudgeI wonder how big the clojure community is compared to the ruby community and the python community and the haskell community and the java community
04:35mudgeclojure is the smallest, right?
04:35RaynesGood question. I'd guess much smaller than all of those due primarily to age.
04:35mudgeyea
04:36RaynesIt would be nice to see real numbers, but I can't think I of a good way to measure anything like that.
04:36mudgei love that clojure is a way for java programmers to get into lisp and functional programming and get it into work
04:37mudgei'd love to hear stories about how employees started using clojure in their work projects, and how they managed to do that and such
04:37mudgemaybe i'll post a question on stackoverflow asking if anyone has any such interesting experience
04:38mudgeor maybe hacker news would be a better place to ask such a question
04:39RaynesProbably.
04:39RaynesOr the Clojure mailing list.
04:39mudgeyea
04:39mudgemaybe both?
04:39RaynesYou could post the question on the mailing list than hackernewsify it.
04:39mudgeyea!, was just thinking that
04:39mudgei think I'll do that
04:39Raynes:)
04:47bortreb]
04:53mudgesubmitted, it will take a little while for the post to the mailing list to show up
04:53mudgeentitled: Getting Clojure into the workplace, how do you do it?
11:05pedroteixeiraanyone knows if it's possible to generate a class with a type in the field, using defrecord?
11:05pedroteixeira(defrecord A [^String name]) (.getField A "name")
11:05pedroteixeira,(defrecord A [^String name]) (.getField A "name")
11:05clojurebotDENIED
11:06pedroteixeirait seems all fields are generated as Object
11:18arohnerpedroteixeira: that's not supported yet
11:19arohnerpedroteixeira: it may come in a future release
11:20pedroteixeiraarohner: ok, thanks. is there any way to read metadata from the record fields?
11:21arohnerI don't think the fields themselves can contain metadata, but the record can, and the field values can
11:21pedroteixeiraarohner: alright. will give it a try!
12:24Licenser:)
12:50dsopI wonder if it makes sense to propose an clojure interface for java's MessageDigest like this http://github.com/dsp/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/crypto/digest.clj for contrib?
15:46neotykHi, is there something like suspend/resume sequence?
15:46AWizzArdneotyk: what would those fns do?
15:46neotyksomething like: (get-when-ready seq callback)
15:46AWizzArdWhat would get-when-ready do?
15:47AWizzArdIs [1 2 3 4 5] ready?
15:47neotykso you register a callback that is triggered when there are more elements in seq
15:47neotyk[1 2 3 4 5] is always ready
15:47AWizzArdYou could think about using watchers.
15:47AWizzArdseq seems to be a mutable object, maybe an atom or a ref. To those you can add watchers.
15:48AWizzArd(find-doc "watch")
15:48neotyk,(doc watch)
15:48clojurebotPardon?
15:48AWizzArdTry find-doc.
15:48AWizzArdIn your repl.
15:48neotyk,(find-doc "watch")
15:48clojurebot------------------------- clojure.core/add-watch ([reference key fn]) Alpha - subject to change. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if a
15:49neotykAWizzArd: that should be able to do the job
15:50neotykthanks, AWizzArd +1
15:50AWizzArdFrom what you said so far it looks very much like the thing you want.
15:51neotykI want to be able to provide something like that for body of POST/PUT
15:52neotykso you can "deliver" values later
15:52neotykthough promise is kind of one time thing
15:53neotykand prefer not to limit user imagination
15:55vibranthello
16:01vibrantis there any alternative to (doall that simply returns a lazy seq?
16:02arohnervibrant: the point of doall is to realize the items of a lazy seq. What would a doall that returns a lazy seq do?
16:03neotykfor?
16:03clojurebotfor is not a loop
16:06vibrantneotyk; that's it, thanks.
16:06vibrantand now i want to make a map from the result :)
16:13AWizzArdvibrant: perhaps you want to begin right away with reduce?
16:13vibrantAwizzArd; that's what I did in the meantime, thanks.
16:13AWizzArdk
16:54amatosI am doing a fairly large Swing application with Clojure. Because I have lots of modal dialogs, I need to have a reference to the main JFrame in most of my functions. Now I don't want to have to pass it around to every function, so I thought of making it global (with def), but that doesn't play well with gen-class right?
16:55amatosBecause if I have gen-class in my namespace, and then a def, that def is visible at compile time, but not during run time when I run my main-
16:55amatosis this right?
16:56arohneramatos: no, the def will still be visible
16:56amatosah ok
16:56amatosSo is this what usually people do with swing applications?
16:58arohneramatos: I haven't done much with swing, but if you're going to create the value once, a def would work
16:58amatosok
16:58arohneramatos: otherwise you can make a ref that contains the JFrame, and refer to it from a def, or the state on the gen-class
16:58amatosI am using the maven clojure plugin, and I have the impression the defs are evaluated when compiling the class
17:00amatosand that evaluation actually screws things a little bit, because I end up having side effects when compiling (like files being generated and so on) caused by the code inside those defs. It is not a big deal, but doesn't sound very clean to me
17:01amatosA ref might be a better idea then, since i can set it up inside main-.
17:02arohneramatos: do you have side effects at the top level, outside of a function body?
17:02amatosyes
17:02arohneramatos: that would cause things to happen at compile time
17:02amatosbecause my defs call constructors that then generate files and stuff
17:03amatosNothing much I can do about it , because that is the way the Java API I am using is set up
17:03amatosSo a ref might be a better idea
17:06amatosActually, what about atoms? I could set them inside my main-, and then refer to them in my other functions. And then I wouldn't need any transactional stuff
17:06amatoswould that work?
17:08tomojit seems like a var would work fine
17:08arohneramatos: yes, that would work fine
17:09amatosso, sorry for my ignorance, but what happens if I do def inside my main-? And how is that different from doing def at the namespace level?
17:09amatosis that a var?
17:09arohnertomoj: what about the side effects at compile time?
17:09arohneramatos: yes, def creates vars
17:09amatosare those defs thread-local?
17:09arohneramatos: and it's possible, but "icky". re-defing is basically allowed only to make development easier
17:09amatosah ok
17:10arohneramatos: no, they're normal, full fledged vars
17:10amatoshum...
17:10amatosyes, doesn't sound that clean as well.
17:11amatosSo might be better to use an atom where I declare them to be nil at the top level, and then reset! them inside the main- function. That sounds somewhat better (although not much cleaner)
17:13amatosat least it is clear in the code that the values might change (although they change only once)
17:13arohneralter-var-root is another option
17:15amatosok
17:15tomojlike (alter-var-root foo (constantly bar)) ? :/
17:15amatos:)
17:16tomoja var and binding in -main would work, but that's probably "icky" as well?
17:16amatosWell, it seems of whatever solution I use, it is always going to be a bit icky
17:17amatosI am trying to understand why does the clojure compiler even bothers to evaluate the toplevel expressions inside that namespace, if the namespace is marked with gen-class, so only meant to be used for compilation?
17:18tomojI suppose you can't move them out of toplevel eh
17:19amatosI can add them inside main-, but other functions need to refer to them. I guess that should work as long as I only call these functions after the defs inside main-
17:19amatosIf I understood correctly, it doesn't make much difference if I do def at the toplevel or inside main-. They are still global within that namespace
17:20arohneramatos: right
17:20tomojwhat I meant is, do you really need a var at all? :)
17:20tomojwell clearly you don't really need one, but the question is whether the code would be uglier without them, I guess
17:21amatosWell, I am trying to avoid having functions with 6 or 7 parameters, where most of them don't actually change
17:21tomojyeah :)
17:21amatosFor most swing stuff, I need to pass the main window, I also have a configuration object that needs to be passed around, I use myDoggy so I need to pass a content manager around, and so on
17:22amatosmost functions will require those 3, and their references don't change.
17:25amatosWell, I will think a little bit more about it. I am tempted to use atoms, defined to be nil at the toplevel, and then reset! inside main-. That seems to be the cleanest solution so far.
17:26amatosthanks everyone for the help
18:15arkhfor vectors, are 'get' and 'nth' the same except nth can optionally throw an exception?
18:23arkhnvm - I should get in the habit of looking at the source
18:27ninjuddchouser: is clojure.java.shell/sh supposed to println the opts?
18:30pedroteixeirawhen using clojure.test, I get weird behaviour regarding java classes. e.g: (testing (do (defrecord R []) (new R) )) does not work.
18:31pedroteixeiraremoving the body from the testing function, the code works..
18:31pedroteixeirais this a bug in how things are getting resolved inside the testing macro?
18:53tomojgrrr
18:54tomoj`mvn clojure:swank` seems to freeze all the resources
18:54tomojwhether you change them in src/main/resources or in target (the latter would already be pretty inconvenient...), you don't see the updates
19:03arohnerhas anyone used the visualvm memory profiler, and got anything approaching realistic results?
19:04arohnermy app is taking ~1GB, and the memory profiler only lists ~5MB in objects
19:13chouserninjudd: no, it's not
19:13chouserthere's already a patch to remove that, it just needs to be applied.
19:13chouserand perhaps reviewed. which perhaps I should do. :-/
19:14ninjuddchouser: ok, just making sure. i noticed it a while back, and figured it would go away eventually
20:15lancepantzi have a lazy sequence, that i'm iterating through and calling a function on only to see if an exception is thrown, how do i decide between dorun and doseq?
20:15lancepantzhttp://gist.github.com/466120
20:15lancepantz(it's a sql ResultSet)
20:18persHello all. I'm starting out with clojure and have a lot of experience with CL. I'm having some trouble writing clojure code. In finding the clojure way.
20:19pers(when (or (= foo :asd) (= foo :qwe)) ...) works find in clojure but I would prefer somthing like CL's (when (member foo '(:asd :qwe)) ...). What is the proper way to do this type of check in clojure? Thank you.
20:20perss/fine/find/
20:21tomoj(when (#{:asd :qwe} foo) ...)
20:21persthank you!
20:21tomoj,(#{:asd :qwe} :qwe)
20:21clojurebot:qwe
20:22tomoj,(#{:asd :qwe} :rty)
20:22clojurebotnil
20:43mudgenhello
20:43mudgenhope everyone had a good clojurisc day.
20:46pedroteixeiraany quick way to convert clojure map to java hashmap, and convert all keys as keyword to key as string? :)
20:52pedroteixeirafound it: stringify-keys
21:44cais2002good morning guys, any idea what's the cause of this problem: Exception in thread "main" twitter.proxy$java.lang.Exception$0: . [] (NO_SOURCE_FILE:0)
21:55qbgcais2002: I think you would need to look at the stacktrace
21:58cais2002how do I get more info about the exception in repl?
21:59qbgThe last exception is bound to *e
21:59qbgTo print its stacktrace, do (.printStackTrace *e)
22:01cais2002ah, good, just saw that in the api.. let me try it out
22:21jkkrameris there a way to directly refer to enum names that are within a java class?
22:46rhudsonjkkramer: The usual Class/FIELD syntax works
22:47jkkramerrhudson: i can't seem to get it to work
22:48jkkramerrhudson: i'm looking specifically at http://code.google.com/p/google-diff-match-patch/source/browse/trunk/java/name/fraser/neil/plaintext/diff_match_patch.java#123
22:49rhudsonSo Operation/INSERT
22:50jkkramer"no such namespace Operation"
22:51rhudsontry name.fraser.neil.plaintext.diff_match_patch.Operation/INSERT
22:52rhudsonSorry, without the diff_match_patch
22:53rhudsonsorry again, with it. (having trouble seeing the nesting)
22:53jkkramerclass not found still. i know diff_match_patch is imported; i can instantiate the class and call its methods
22:54rhudsonIf it's imported, then diff_match_path.Operation/INSERT should work
22:54jkkramerit doesn't
22:55jkkrameri can use .name and check enum values string-wise, but that seemed roundabout
22:55rhudsonYou might have to (import '[name.fraser.neil.plaintext.diff_match_patch Operation])
23:00jkkramer(import 'name.fraser.neil.plaintext.diff_match_patch$Operation) is the magic invocation
23:00jkkramerrhudson: thanks for your help
23:00rhudsonah