« August 2009 | Main | October 2009 »
September 28, 2009
This weekend, I did something very, very strange...I gave a talk at C4.
What was strange wasn't the giving a talk at a conference. That I've done a few times. Well, more than a few time. It was more that I, an IT manager was giving a talk to a crowd that is as un-IT as can be: Indie Developers. By and large, this is not a group that is particularly IT-Aware. That's not a good nor a bad thing mind you. It just is. There's a variety of reasons for this, none of which I'll go into here.
First off, thank you very much Wolf, for giving me a chance to speak and a completely open topic. It was...interesting trying to come up with something for this group, and it was something I spent quite a bit of time pondering about. But, based on past experience, the idea was fairly obvious, especially for a group that in general, is very personally invested in their work: Dealing with people who are...shall we say...harshing on them online. (There was a certain amount of amusing coincidence in me picking that topic, as it turned out.)
The talk seemed to be well-received. Then again, zooming pictures of angry badgers are funny.
But, to be honest, I was never quite...comfortable here, outside of 1:1 conversations with people, especially Mike Lee. Warning to all...if you get former aircraft maintenance people swapping stories, that shit can go on for days. But it was a lot of fun, I don't often run into people with whom I can really share that part of my life with, who can really understand the rough humor of it. Any chance I get, I'm buying Mike a few beers.
The thing is, it wasn't that anyone was hostile to me, or anything like that. But, just like an anthropologist living amongst the members of a strange, new tribe doesn't really have a lot in common with the people of that tribe, well, an IT guy doesn't have a lot in common with indie developers. That's not a bad thing, it's just reality. I'm not creating something wonderful, I'm trying to keep shit working, now, and in the future. The way I approach things is really quite foreign to a lot of these folks, and vice-versa. As I told Jason Snell and Dan Moren from Macworld: "I feel like an anthropologist". Everyone was great, but there's just a level of separation that was always there, and so I was never going to really be a part of things.
Aside from the background differences, there was a certain...constant to conversations that comes from acquiring a certain amount of notoriety. Sometimes it was verbalized, other times it was the expressions of "My GOD! He can hold a normal conversation!" Pro Tip folks: you can read this blog from front to back, and you still won't know me, just certain, specific slices of me. That's true of any website/blog. Not to use Mike Lee as Example Man, but even though I read his site whenever he posts new stuff on it, I learned more about him as a person in a few hours of real-world conversation than years of reading his web site could ever tell me. Just because you read words doesn't mean you know the person.
But, my...rep is what it is, and so even though it can be a bit of an obstacle. For example, I do believe I'm the first, and probably only C4 speaker to be told on the twitter backchannel I was boring because I wasn't being a big enough asshole "off the bat". Um...okay, and as we'll see, unintentional irony. (Also, if you're going to talk shit about someone, then man the fuck up and don't pull a lamer backpedal that doesn't even make sense when you get busted on it. You were badass enough to say it, be badass enough to own it. If you realize what you said was wrong, then man the fuck up and apologize and admit you made a mistake.) I heard some variants on that from others in person, albeit more of the "dude, you didn't cuss at all" variety. Time and place folks. I tend not to cuss when I present. Unless I'm presenting in a bar.
So, even though I did have a good time, there was always this sense of separation from things, like I was always observing as much as anything else. (Not that I wasn't having fun with people. Especially damned near scaring Dan Pasco into a new pair of shorts. Saying BOOGABOOGABOOGA to someone really into their iPhone GPS while they're walking down the street? Funny.as.shit.)
So there was always this surreal feeling to things. Fun, but surreal. On the other hand, I got to walk around a city I hadn't really been in since I was....well in over 30 years. Got to see some things I only vaguely remembered. That was way cool.
Oh, and 'the thing'. So there was one talk that was...hmm...you ever been at a presentation, and you can just tell the person doing it is just not into it, not fully engaged, the thing they're talking about is cool, but has some real issues, and they just never figure out how to get the audience into it?
Yeah, one talk went like that. It was good..but not...good.
The backchannel on the guy was...not uniformly supportive. A few people have called it harsh, mean, what have you. Honestly, it was the best example of the difference between my world and the normal C4 attendees' world. (Go to the C4 twitter page, and start about here. ) The basic concept of the talk, about using Appcelerator Titanium to build applications on multiple devices with multiple languages is cool...in theory. The problem was...the talk that was given wasn't the talk that was needed. To be fair, the speaker's wife is ready to have their first(?) child, and you could tell, even if you didn't know this, that he was distracted. The energy was wrong, the presentation was a bit too...not targeted well. It was just a set of issues that while would not have been bad separately...all at once...the backchannel was not terribly supportive.
Some "Pro" tips here, for both the Appcelerator guy, and really, anyone speaking at a highly focused conference:
- Do not, under any circumstances, speak to people who have spent a not-small amount of money to be in that room, and not be committed, fully, to that moment. If you have a major life-changing event about to happen, and you cannot set that aside for an hour, then do yourself, and everyone else a favor: either ask someone else to present for you, or bow out. I can admire the guy for soldiering on, but he did the audience, and more importantly, he did himself a disservice by not being brutally honest and saying "I can't really do this right, I need to not do this, not this time. Next time, sure. But this time, my head is in the wrong place, and I need to be where my head is at, and this week, it ain't in a hotel conference room." I don't think anyone would have thought ill of the guy for calling in a sub, or bowing out. I know I wouldn't have. When you aren't brutally honest with yourself, you find that others will fill that need.
- Know your audience. I knew that what I was speaking on had direct applicability, because pretty much everyone in the room had, at some point, had to deal with someone being really pissed at them. Titanium is cool, but it wasn't shown as something that a room full of Objective-C wizards would find useful. It kind of was a bit of a muddle of "You can use every scripting language known to target three mobile platforms and the Mac, and that's cool." Well, yes, it is cool, but so's ice cream. Even as someone who thinks about such things from the POV of "yeah, my devs could use that, it would be useful", I never really saw where I'd want to recommend it. The fact that the answer to "how do we debug a titanium application written in 4 languages in the same project" was, essentially, "yeeeaaaaahhhh...we haven't figured that out yet" was a bad sign. If you're going talk about something that covers a rather immensely large area, instead of bouncing between feature bullets, point out specific things that will make thing better for an indie Mac dev. If you aren't sure what your audience cares about, ask before the conference starts. Talking about products outside of a comfort zone is good. Doing it in a way that makes people dismiss your product is not good.
- We want to know why your product is good based on your product being good, not because it's not <product>. The fact that Titanium is not Adobe Air is not a reason to use Titanium. Not being the other guy doesn't get you a win. Screw the competition, tell us why, show us why your stuff rocks. A couple of focused demos would have done more to explain titanium than any number of bullet poins.
- Don't be afraid to break the presentation rules. Just because it's a presentation, you don't have to use presentation software. Honestly, spending 40 minutes showing a decent little application written in difference languages, and then targeting each language's version of that application to three mobile platforms and the Mac would have done so much more to show why we should care about Titanium than slide after slide of trying to talk you through a concept that everyone in the room understood, but wasn't supportive of.
Wolf was pissed about it. I don't think he was, as one person says, between rage and tears, but he was unhappy. I get that. You work hard to put together a good conference, you have a speaker flame out for whatever reason, and the audience is less than perfectly supportive of them. That sucks, and it sticks in your craw, because it's counter to what you see the people at the conference as.
Another pro tip: People, even indie Mac developers, are people. They are going to not always act the way you want them to. However, if you are going to run a backchannel, then for the love of dog, monitor it. When you see it going bad, don't just sit there and get angry. Get up and throw the guy a lifeline. Step in a bit, and give the guy a leg up. Ask him the questions that will help him get back on track, or get on track in the first place. There were a few opportunities where that could have happened, but they didn't. Usually, once people start digging themselves into a hole, they may try to dig themselves out, but digging never fills in the hole, it just makes it deeper. That's a hard judgement call to make, and I know that Wolf, at the time, thought he was making the right call, or even didn't really realize that this talk was not doing as well as it should have. It's not easy to say "time to pull his ass in out of the wind", because it's like relieving a pitcher. There's no way to do it without someone feeling bad.
As well, if you're going to say something about what you felt was bad audience behavior, especially when you're in charge...always, always, always do it from a point of calmness. There are time when anger is appropriate, but if you're going to be basically dressing down a group of people, you need to be calm, and you need to not do it in a way that involves ultimatums. Even when well-intentioned, ultimatums are a bad idea, especially if that wasn't your intent. And if you're going to do it in defense of one speaker, then do it in defense of all of them.
Because when you don't, you send another message: "It was okay to make a rude comment or two about this guy, but not that guy". Speaking as this guy, that kind of sucks. No, being told that I'm not being a big enough asshole, and because I'm not, I'm boring, is not going to offend or hurt me. You don't get to be me without realizing that there are certain rules that ignore you. But, if you're going to scold about fair play and decency, then don't be leaving people out, just because "oh, it won't bother him." It may not, but that doesn't mean they won't notice it.
| Comments ()September 27, 2009
filing a bug with DTS on DTS:
Radar # 7256673:
DTS needs to provide code-level support for AppleScriptObjC developers. Also on Open Radar.
If you want DTS to support AppleScriptObjC, go and file many, many duplicates.
| Comments ()September 23, 2009
Oh, one major thing
To those of you who dropped a dime, or in one case, rather a few dimes on my paypal account after my bit of kvetching on Twitter about the relative uselessness of PayPal buttons: Thanks. Not just for the ducats, but for the thought as well. One advantage to being a cynical bastard is that when people do nice things, it's always unexpected, so it always means something, because you understand the fallacy of the "Arrogance of the Good Person".
I definitely never make it easy on y'all but you did a kindness anyway, so thank you, very much.
| Comments ()This is going to cause a wormhole
The most insane man in computing, Larry Ellison, with one of the sanest talks about CLOUD.
When Larry Ellison is a source of cogent, sober commentary...DUCK! IT'S THE APOCALYPSE!
| Comments ()Oh Cthulu, here we go
So I posted my article about the Apple file handling debacle in Snow, (and just in case i wasn't clear enough, i was wrong about a few things in that, and Apple really is screwing the pooch here), and lo, the 'real' programmers come down from the mountain, and tell me how using UTIs to tell the OS what fucking application to open the fucking file is some kind of heresy, and will break UTIs, break the OS, break physics, fuck, I don't know, it's all bullshit.
The latest entry is from Peter Hosey, How not to use UTIs. It's yet another entry in "why developers have a hard time figuring out why people hate their software, because they are too wrapped up into ideological purity to get shit done." Peter's problems, and they are many, at least within his article, exactly represent the kind of narrow-minded worship of ideological purity that the idiots at Apple who think that all you need are filename extensions have that caused this fucking problem in the first place.
Now, into the stupid:
No. Uniform Type Identifiers are a replacement for type codes (and MIME media types, and filename extensions), not for creator codes. There is no replacement for creator codes.Uniform Type Identifiers are just that: They identify types of data. Using them for anything else is misusing them.
Oh fucking spare me. First of all, the UTI entries in an info.plist file most certainly DO identify the 'creator' of the UTI, aka the part of the UTI that is the bundle identifier. In Coda's case, the bundle identifier is com.panic.coda. Why is that better than a creator code? Well, for one, because you have more space. For example, both Acrobat 7 and Acrobat 8 use the same creator code: CARO. So does Acrobat 9 for that matter. If adobe wants to differentiate in the creator code, it has to create and register a new one. That's where you run into real problems, because getting useful information out of 4 characters is a bit hard, especially under a system that's been in use for twenty fucking years. At some point, you run out of space. However, using the bundle identifier, this is fucking trivial, because you can do something like com.adobe.acrobat7 or what have you. Bundle Identifier win.
When we look at the exported type UTI section of Coda's info.plist file, what do we see? They all start with the bundle identifier, aka A BETTER VERSION OF A FUCKING 4-CHARACTER CREATOR CODE. Guess what Peter? That creator code information? IT'S ALREADY IN THERE. Yeesh.
So then Peter goes off about my CSS example:
And that identifier is wrong, because CSS is not Panic's format.I use CSSEdit. Currently, it doesn't declare a UTI, but if they should follow Coda's example, they should make one up of their own, such as com.macrabbit.cssedit.css. Now we have one type with two names. Which is right?
They both are. Look, i know that the idea of multiple right answers is hard for an idealogue, but follow the fuck along for a minute. What both of those UTIs, (at least in my view, which is anything but ideologically pure) are saying is "this is a file of type CSS that should be opened by <application>. That, by the way is what the combination of a file type and a creator code did prior to Mac OS X 10.6. It said "this is a file of type foo, and it should be opened by application bar. A perfect example of this was a text file. Text files all had the same type: TEXT. But depending on what application created it, the creator code would be different. ttxt, R*ch, whatever. The fact that a file had a specific creator code did not, in any way, shape, or form, prevent another file that could handle that file type from correctly opening it. All it really meant is that when you double-clicked the file, the application that was represented by the creator code would open the file.
There is nothing about com.macrabbit.cssedit.css vs. com.panic.coda.css that creates any more problems than TEXT/ttxt vs TEXT/R*ch did, unless you're going to tell me that Mac OS 9 was far more sophisticated and better at this than Mac OS X is.
Suppose I write an application that accepts CSS data. Which UTI do I look for: com.panic.coda.css or com.macrabbit.cssedit.css? Should I look for both of them? What if I find both? What if a third developer releases a CSS editor? Now I have to keep up with the entire population of Mac CSS editors just to accept all the many names for one type.
No you don't any more than applications had to in the fucking good old days. What needs to happen is that the OS has to have some added functionality that lets an application say "Hey, what the fuck is com.panic.coda.css", and the OS, already having logged this information, thanks to the same Launch Services functionality that exists today can say: "it's a file of type CSS that also conforms to public.plain-text, and to the public.filename-extension of css." Then your application says "Fucking cool, I can deal with that, open away." That's letting the OS on a specific machine do its job, so your application can do its job too. See, you don't have to maintain an app-specific list of this shit, that's what the OS and mechanisms like Launch Services are for. Peter's argument is just silly here.
The right type identifier would be something like org.w3.css or org.w3.cascading-style-sheets, following the rule that the type should be named after whoever controls it. The W3C controls CSS, so its UTI should be named after them. Some other formats, such as PNG, aren't controlled by anybody, so they go in public.
All hail the cause of ideological purity making shit useless for all. Hail Cthulu!
You might point out public.html and public.xml, as both of those are also controlled by the W3C. Obviously, I disagree that these should be in public.*. But it's too late to change them now, so we have to put up with them.
Bless your heart. Peter's insistence on ideological purity uber alles is showing a bit. It's not a good look
Better examples include com.adobe.pdf and com.microsoft.word.doc. In each of these cases, some third party controls the format, so they get the format's UTI named for them. Notice that Preview does not invent a com.apple.preview.pdf UTI, and TextEdit does not invent a com.apple.textedit.word.doc UTI; they use the UTIs named for the creators and maintainers of those types.Peter is confusing two entirely different issues here, and I'm not sure why beyond he overdosed on his idealogue pills this morning. The standard that defines a document or file type, where one exists, has fuck-all nothing to do with what application should open it on Bob's Macbook. In fact, there's no reason whatsoever that TextEdit couldn't have a UTI of com.apple.textedit.word.doc that also conforms to com.microsoft.word.doc. All it would do is tell the OS "hey, if the file has this metadata associated with it, open it up in TextEdit". Thanks to Launch Services, if for some reason, another application that can handle com.microsoft.word.doc files wants to open that file, it would be able to, without knowing fuck all about TextEdit.
Okay, let me just say something. None of this shit will prevent an application from opening, or trying to open a file, unless the programmer is really short-sited and says "unless a file perfectly matches this list of conditions, don't even try to open it." While that does happen, it's pretty fucking stupid. If i want to try to open PDFs in Word, fuckit, lemme try. The worst that can happen is that it will fail, and Word might crash. Big deal. You cannot prevent stupidity, so stop trying. Just fail gracefully when it happens.
Onward and upward. I'm going to skip some of the more blindly ideological shit, it's just kind of dumb. Some random hits:
Coda CSS file props:displayed name:"test.css",
creator type:"TStu",
type identifier:"com.apple.traditional-mac-plain-text",I'm surprised you didn't notice this. Why isn't this file's type identifier com.panic.coda.css?
Because Apple's fucking stupid, and not letting applications explicitly set this, and so we have the problem in Snow.
Yeah. Cocoa makes it difficult to apply a creator code to a file and doesn't do it automatically, so expect most Cocoa apps to not do it.
So then how the fuck do Cocoa applications deal with this? Well, usually the filename extension. that's right. you want to completely bugfuck a Cocoa application's ability to open a file from a double-click in the Finder, change the right part of the fucking filename. All hail the glory of Unix purity. Hail Cthulu.
It matches what you got when you assigned the default handler of a file type, as well. That's what you did the newer equivalent of.There never was a way to set which application opened files that had a given creator code. That was what the creator code was for: Determining which application would opened the file.
No shit sherlock, and that's what i'm saying to extend UTIs to do as well, since they're 90% of the way there already.
Sort of. They've been warning that they'd kill off the combination of file type codes and creator codes. UTIs are the replacement for file type codes; as I said above, there is none for creator codes.
Bundle Idendifiers, which are, rather a lot, part of the fucking UTI. Jesus, this is not fucking hard to figure out.
Actually, it was more common to use filename extensions. See what I said above about the difficulty of assigning file types and creator codes from a Cocoa app. I think that was actually quite rare, simply because filename extensions were so much easier.
I've got a very short AppleScript that will show you how stupid an idea it is to absolutely rely on filename extensions for this. Fuck, i don't even need that. Here, let's play "file names are not reliable metadata" using the Cocoa way:
- Here's a file: test.css. What kind of file is it? Well, we hope it's a CSS file. We don't know, but since all we are allowed to use is the filename extension, css file or fucking jpeg, it's opening in whatever the OS has decided should open .css files.
- Oops, Bob the technologically illiterate user renamed it test.jpg. The file itself hasn't changed, but we don't care, because we are doing things in an ideologically pure fashion. The filename extension is now .jpg, it is now and forever a jpeg file, and will open in some form of image handling application. Won't that be fucking fun
- Did I say forever? Oops, i meant until bob decides it's obviously the fucking extension that is makeing his Macbook go insane, and just lops the fucker off. Now what kind of file is it? WE DON'T KNOW, because according to our ideologically pure way of life, only the file extension can be used to decide what application opens anything.
In fact, were we to be that pure, we'd not allow Finder to dirty our nice pure file with a resource fork, because that's not the fucking Cocoa way.
All hail slavish ideology. Hail Cthulu.
No, it doesn't. The creator code information is still available, and the OS ignores it. The OS now only uses type information to determine how to open a given file, except for files that the user has assigned a specific application to.
That's pretty fucking handy. Oh sure, you spend hour creating that PNG in Photoshop, but now, to open it in Photoshop again you have to:
- Open Photoshop first, THEN open the file. Fuck that double-click convenience, this is ideology pal!
- Change the default PNG handler for EVERY FILE, (assuming of course, you're using filename extensions. If you aren't, you have to, because sans anything else, the OS now has no fucking clue as to how to handle a file without an extension. I really missed DOS, didn't you?
- Use the Finder to add a resource fork to the application, which will break if Photoshop's location ever changes, because it's using a static file path. Whoo-hoo! Relive the glory of 1983!
Thank GOD we didn't sully the purity of UTIs by using them to make the user's life easier. After all, fuck the user, it's all about making sure programmers never have to go near that dirty, dirty pragmatism.
Agreed. I say it should set the file's creator code.Incidentally, I tested in Tiger, Leopard, and Snow Leopard, and Finder did this resource trick in all three versions. If the Info window ever did set the file's creator code, it hasn't done that for many years.
Creator codes are dead dude, get over it. That implementation always had issues to begin with. But, I'm glad that your ideological purity makes you back an idea that firmly binds an OS designed for 2009 back in 1984. Fuck really improving things, we'll just keep adding layers and layers of shit until we've accounted for every possible edge case.
And now you know why smashing type information and creator/opener information into a single value is a bad thing.
No you fucking idiot, that's not what I said at all. but you're a fucking idealogue who probably gets hives at the MENTION of the word "pragmatism", and i've already explained why you're full of shit, so fuck you.
There is no reason why the average user should be able to change the type of a file. If they created an HTML file, it's an HTML file, and there's no reason for a user to be able to set it to anything different unless they really know what they're doing. (I've done it, and I'm assuming you have, too. We're exceptions.)What you want to do is to change which application opens the HTML file, and that is completely separate from the fact that the file contains HTML.
Again, you're wrong. Adding a piece of metadata that reads as "com.panic.coda.html" and is interpreted by the OS as "when you double-click on this file, if Coda is on the system, then open it in coda, otherwise, since this conforms to public.html, use the default handler for that. If that doesn't have a handler, then try the filename extension. If there isn't a filename extension, then fuckit, ask the user, something's not right anyway, not my job to guess."
That's not going to break a fucking thing, and it's not jamming all the information into one value. As well, as a programmer or the OS, it's not your job to tell me what kind of file i want to make something. For one thing, really, there is no such thing as an HTML file. It is a text file. Period. The only difference is when the right application reads the file and interprets the data. Since you're so against 'changing' files, then regardless of what the content of the file is, if it is a plain text file, the ONLY default application should be whatever is the default for plain text.
That, by the way is the kind of asinine logic that ideological purity gets you.
You want to live in that world, where you can only use filename extensions, or the OS can never, ever progress beyond 1984 without inventing some completely different mechanism that would STILL have to fit into Launch Services and most likely be effectively indistinguishable from just sucking it up and using the information we already have today for this shit, you go right the fuck ahead, but I'm not going wait around another ten years just so you can have your ideologically pure spankfest. I have work to do, and users to support, and UTIs solve far more problems than they cause.
| Comments ()September 22, 2009
UTI's don't work if you don't set them correctly [UPDATES]
So, the latest brou-ha-ha over Mac OS X 10.6 is APPLE HAS ABANDONED CREATOR CODES AND NOW YOU CAN'T ASSIGN DOCUMENTS TO OPEN IN THEIR CREATING APPLICATION AND OMG STEVE JUST ROBBED MY HOUSE!
UPDATES AT BOTTOM
Okay, the last bit, about Steve robbing the house is hyperbole, but, the general tone of what I'm reading is pretty much nailed there. Daring Fireball, rosscarter.com, and (the most sober of the bunch), TidBITS have all gotten on the "Apple has abandoned creator codes, now we're screwed, damn you Apple" bandwagon. They're all right about one thing: Apple has dumped creator codes in Snow.
So before you panic, there's a replacement mechanism, the UTI, or Universal Type Identifier. (Is it just me or does Apple consistently come up with some bad acronyms. The acronym for AppleScript Studio. UTI. Seriously bad acronyms here.) The idea here is that instead of a cryptic 4-character code, (Seriously, "8BIM". "WDBN". There's nothing intuitive about that), you instead use a plist-style convention. So, say I create a CSS file in Coda. Of course, Coda will give it a .css file extension, but that's not going to bind that CSS file to Coda in and of itself. Instead, it's going to bind it to whatever the default application for .css files are on my system. On my Mac, the default for .css files is BBEdit. So sans creator codes, if all the OS has to go on are file extensions, unless I specifically change the default, .css files will open in BBEdit.
That's not broken mind you, that's just how it works when all you have is a file extension. Now, with a creator code, (in this case, Coda's is "TStu". See, how could you not just know that stands for Coda?), this is easy. Coda attaches that creator code to the file, and even though the default is BBEdit, it opens in Coda.
Since I'm on Snow, that won't work. So there's a third option, the UTI. Ideally, Coda should assign an application-specific UTI for CSS files it creates. As it turns out, Coda is a UTI-aware application, and according to Coda's info.plist file, that identifier is com.panic.coda.css. More verbose than a creator code, but infinitely more readable and useful.
So what's happening in Snow? Why is all of this failing? Why did Apple screw us all over.
Well, as it turns out, it's not all Apple. It's partially Apple, but not all Apple.
As a test, I mimic'd what Ross Carter did and created some files. A .txt in BBEdit, a .html in Coda, .css in Coda and a .PNG in Photoshop. So we have a good mix of old and new, Carbon and Cocoa.
.txt opened in BBEdit.
.html opened in Safari.
.css opened in BBEdit
.png opened in preview
Ross's experiment replicated nicely on a different machine with different applications. Looking at the settings for my OS in RCDefaultApp, this is as expected for the extension.
But what about the UTI?
Hm...okay, let's look at those. A bit of AppleScript to pull the type identifier for the file:
set theFile to choose file
tell application "System Events"
set theProps to properties of theFile
end tell
So let's take a look at the file properties for those four files, according to System Events. (Keep in mind, I'm assuming that what SE is showing me is the truth. If it's showing bad info, then all my conclusions are bad as well.)
BBEdit Text File props:
class:alias,
short version:"",
container:folder "Habu:Users:jwelch:Desktop:UTI Test:" of application "System Events",
path:"Habu:Users:jwelch:Desktop:UTI Test:test.txt",
file type:"TEXT",
volume:"Habu",
physical size:4096,
URL:"file://localhost/Users/jwelch/Desktop/UTI%20Test/test.txt",
id:"test.txt,-100,200367325",
displayed name:"test.txt",
busy status:false,
kind:"BBEdit text document",
creator type:"R*ch",
version:"",
name extension:"txt",
POSIX path:"/Users/jwelch/Desktop/UTI Test/test.txt",
name:"test.txt",
modification date:date "Monday, September 21, 2009 12:40:09 PM",
size:20,
type identifier:"com.apple.traditional-mac-plain-text",
package folder:false,
stationery:false,
creation date:date "Monday, September 21, 2009 12:40:09 PM",
visible:true,
product version:""
Coda HTML file props
class:alias,
short version:"",
container:folder "Habu:Users:jwelch:Desktop:UTI Test:" of application "System Events",
path:"Habu:Users:jwelch:Desktop:UTI Test:test.html",
file type:"TEXT",
volume:"Habu",
physical size:20480,
URL:"file://localhost/Users/jwelch/Desktop/UTI%20Test/test.html",
id:"test.html,-100,200367398",
displayed name:"test.html",
busy status:false,
kind:"HTML document",
creator type:"TStu",
version:"",
name extension:"html",
POSIX path:"/Users/jwelch/Desktop/UTI Test/test.html",
name:"test.html",
modification date:date "Monday, September 21, 2009 12:42:34 PM",
size:18832,
type identifier:"com.apple.traditional-mac-plain-text",
package folder:false,
stationery:false,
creation date:date "Monday, September 21, 2009 12:42:34 PM",
visible:true,
product version:""
Coda CSS file props:
class:alias,
short version:"",
container:folder "Habu:Users:jwelch:Desktop:UTI Test:" of application "System Events",
path:"Habu:Users:jwelch:Desktop:UTI Test:test.css",
file type:"TEXT",
volume:"Habu",
physical size:4096,
URL:"file://localhost/Users/jwelch/Desktop/UTI%20Test/test.css",
id:"test.css,-100,200367430",
displayed name:"test.css",
busy status:false,
kind:"BBEdit text document",
creator type:"TStu",
version:"",
name extension:"css",
POSIX path:"/Users/jwelch/Desktop/UTI Test/test.css",
name:"test.css",
modification date:date "Monday, September 21, 2009 12:43:58 PM",
size:100,
type identifier:"com.apple.traditional-mac-plain-text",
package folder:false,
stationery:false,
creation date:date "Monday, September 21, 2009 12:43:58 PM",
visible:true,
product version:""
Photoshop PNG file
class:alias,
short version:"",
container:folder "Habu:Users:jwelch:Desktop:UTI Test:" of application "System Events",
path:"Habu:Users:jwelch:Desktop:UTI Test:test.png",
file type:"PNGf",
volume:"Habu",
physical size:1490944,
URL:"file://localhost/Users/jwelch/Desktop/UTI%20Test/test.png",
id:"test.png,-100,200367506",
displayed name:"test.png",
busy status:false,
kind:"Portable Network Graphics image",
creator type:"8BIM",
version:"",
name extension:"png",
POSIX path:"/Users/jwelch/Desktop/UTI Test/test.png",
name:"test.png",
modification date:date "Monday, September 21, 2009 12:46:45 PM",
size:1489781,
type identifier:"public.png",
package folder:false,
stationery:false,
creation date:date "Monday, September 21, 2009 12:46:29 PM",
visible:true,
product version:""
So now we see a problem. All the text-ish files have the same type identifier: com.apple.traditional-mac-plain-text. The Photoshop PNG file is typed as public.png. For all three text-based files, they all have the same file type, "TEXT", they all have the same UTI, com.apple.traditional-mac-plain-text. The only two things the OS has going for it are the extensions and the creator code. If you take away the creator code, you're screwed, because all you have are the extensions.
While I agree that this is frustrating, why aren't any of these applications doing the right things? Pages '09 does. It sets the type for .pages files to "com.apple.iwork.pages.pages". Unsurprisingly, it doesn't even have a creator code. There are only two bits of data to work with, the UTI and the file extension. In fact, playing around a bit, I found that in general, Mac OS X pays attention to the UTI rather nicely. For example, when I export an OmniOutliner file as HTML, the UTI is set to "public.html" and on my machine, the default for that was Safari. Even thought the default for the .html extension is BBEdit, the UTI overrode that. When I changed the handler for public.html to BBEdit, then the file opened in BBEdit. That's exactly the behavior I'd expect, and it matches what you got with Creator Codes.
However, there's more to the algorithm than that, as the handler for "com.apple.traditional-mac-plain-text" is BBEdit, yet the HTML file opened in Safari, which was the handler for .html. Clearly there's some subtleties to the UTI-extension interaction that need to be better documented. (Gee, there's a shock, Apple's documentation not complete.)
Thus far, the issues here are many. Yes, Apple did abruptly kill off Creator Codes, however, they've been warning about that for some time now. UTIs are the future, go there. Out of the three applications I used to create the files, only one, Coda, even has UTI support in its info.plist file. Neither BBEdit 9.2.1 nor Photoshop CS4 even hint at them. According to RCDefaultApp, which lists all the UTIs registered on my system, the only Bare Bones application with UTI support, out of the three on my Mac, is Yojimbo. Adobe only supports UTIs for EPS, Flash, Illustrator, PDF, native Photoshop, a few different kinds of postscript listings and RAW. So out of all of them, only Coda even had a chance to use UTIs for its files, and even though it supports UTIs for .css files, it doesn't set them correctly. If it had, the type identifier for that CSS file should have been "com.panic.coda.css". Now, I know that 'simple' is a big fat lie when it comes to application development, however, at some point during the 10.5 lifecycle, all these applications should have been updated to not only support UTIs, but to use them. Instead, they all relied overmuch on FIle Types/Creator Codes, and now that those are gone, well, the OS does what it can with the information it has available.
As we see by the examples I cited, when the information is properly used, the OS tends to do the right thing. But you have to at least try here folks. Computers suck at guessing, and without a UTI, that's what you get: a computer's best guess.
So it's clearly not Apple's fault? Welllllll...no, that's not completely correct.
What happens if you delete the extension? What should happen is nothing. The UTI should remain, and the file should open correctly. What actually happens is quite a bit different, it all sucks, and this suckage is Apple's fault. For example, what happens when you delete the file extension on a Pages '09 file? Well, the UTI changes to "dyn.age8u", and the default application in the "Get Info" changes to TextEdit, but when you double-click the file, it gets passed to Archive Utility. That makes sense in one small way, as Pages '09 files are technically zipfiles. But that's really stupid, because the file hasn't changed, just some user-modifiable metadata. If you remove the .oo3 extension from an OmniOutliner file, the OS or the Finder, (not sure which here, and I admit, I don't really care), decides that because it's a bundle file, (a folder masquerading as a single file), that in spite of the fact that the UTI clearly indicates what file it is, if you remove the extension, obviously you wanted it to become a folder again. That's stupid on a really, really stupid level. It wraps back around and laps itself, that's how stupid this is. What should happen, from the human perspective, is...nothing. The UTI wasn't changed, just the file extension, and in this case, that is not the user indicating they want to radically change how the file is opened. The only exception is where there is no UTI information for the file. In that case the user should get the "Hey, you're removing the extension, and weird stuff might happen if you do" dialog.
If the user changes the extension to something else, and that new extension is not one the current default application can handle then what should happen is a dialog that says "Hey, you're changing the extension to one that <current default application> doesn't handle. Do you want this to be opened in <new default application> instead?" That at least warns the user in a case where a warning makes sense, because they're taking an action that normally indicates they want to change what opens the file.
So in this case, there's plenty of fault to go around. Applications have to start supporting and correctly using UTI information. Apple has to fix the OS so that removing and/or modifying extensions is handled correctly by deferring to the UTI whenever possible, and Apple really has to better document UTI interaction. (Even if they make existing documentation easier to find. Hard to find docs help no one.)
Oh, and what about when you change a file association in the Finder? Well, unsurprisingly, the Finder cheats. It adds a resource fork to the file with the path to the desired application coded within. Along with better handling of filename extension vs. UTI issues, maybe the Finder could start doing the right thing too?
UPDATE
It turns out that I was the victim of an erroneous, albeit understandable assumption, namely that Apple allows you to set the UTI for a file. You can't. What you have to do is declare a UTI that corresponds to the extension/mime type/OStype of the file.
So basically, the only way, from what I can tell, based on the info I'm getting to 'set' a file's opening application in Snow is:
- Create a unique extension for every file your application normally creates, using 'standard' extensions only for 'exporting' files, even if you're exporting a text file to a text file.
- Create a resource fork entry for your file that manages to create a path to the opening application
If this is really the direction Apple is taking for Snow and Beyond, well, I have a word..no, two words for it:
Fucking Stupid
It is Fucking Stupid to do this. If the only way to have a unique UTI associated to a file is for that file to use a completely unique file extension, then WHAT THE FUCK GOOD ARE UTIS? Fucking seriously, why the FUCK bother? BBEdit creates TEXT FILES. Does Apple seriously expect that Bare Bones, to properly use UTIs, is going to now create a .bbedittext extension, a .bbedithtml extension, a .bbeditohmyfuckinggodwhatthefuckisgoingon extension, then make you EXPORT to 'standard' extensions, just so you can know a file created in BBEdit will open in it?
If this is what Apple is pushing, non-settable UTIs that are only 'inferred' because of (now) one piece of data, the filename extension, this is fucking inane. Like "stop huffing model glue" inane. Jesus, does someone have to write userspace trojans that blow out filename extensions on login or at random times, under snow, just to watch people be unable to fucking work before the NeXTards at Apple STOP FUCKING JIZZING ON THE FILENAME AS THE ONLY RELIABLE WAY TO ASSOCIATE THE FUCKING FILE TO THE APP?
If this is what Apple is pushing, then everyone who signed off on non-settable UTIs is a fucking idiot, and Cthulu below, I would LOVE to be wrong here, and have someone point me to the docs where you can set UTIs on a file manually.
| Comments ()September 21, 2009
Installing Cacti on Mac OS X 10.5 Server
So, as promised, here is the Cacti version of my Nagios articles, (here and here.) Note, if you do not have a lot of experience with SNMP, you'll want to read up on that, as Cacti is all about the SNMP. I've a couple articles on those too. A primer here, and one focusing specifically on SNMPv3 is here.
Basic Install
Fortunately, setting up Cacti is really simple, and the docs are reasonably solid, with only a few things that tripped me up. For me, the biggest annoyance was creating the MySQL Database, mostly because I just don't deal with MySQL that much, so I tend to gradually forget what I've learned. I didn't have to spend a lot of time mucking about with the PHP configuration. In fact, as I remember, I didn't mess with the PHP config at all.
For MySQL, since I'm running Cacti and Nagios on the same box, I'm using the "nagios" user as the MySQL user for Cacti, and that user has full control over the Cacti DB, but only on that machine. I also highly recommend not allowing root MySQL access from anywhere but the physical MySQL server.
You can put Cacti anywhere you want on your machine, as long as Apache knows about it. I install it inside of /usr/local/nagios/share/, which is the root directory for my Nagios site, and symlink then actual Cacti install directory to /usr/local/nagios/share/cacti, so that I can take advantage of my Nagios setup, and make upgrades/rollbacks easier.
Actually installing Cacti is pretty simple:
- Download the Cacti distribution
- Unpack it in location you want it to be, and set the user/group permissions as needed.
That's the basic install for Cacti: Pretty simple, but there's a few more things to do before we can start configuring Cacti. (One thing I highly recommend is not renaming the Cacti directory to just "cacti", but rather making a symlink for that. As I said before, it makes upgrades and rolling back FAR easier.)
You'll need to make sure you have RRD installed, as Cacti needs that to actually create the graphs you'll view. I install RRD from MacPorts, one, because it's much simpler, (RRD has a lot of requirements & prereqs), and two, because with MacPorts, it's not installed in system directories, so OS updates are less likely to mess you up.
RRD
With the current version of Cacti, (0.8.7e), you want to make sure you are current on your version of RRDTool. I'm using 1.3.6 with Cacti, and it seems to work fine. If you upgrade RRDTool, you'll want to do so in a way that lets you revert easily (such as MacPorts). I've had to do that once or twice when I installed a too-new version for Cacti to work with.
MySQL
You'll also want to make sure the MySQL libraries & headers are installed as they aren't installed by default in Leopard and Leopard Server. (Yes, I agree, stupid.)
If you haven't yet done so, you'll want to set up and configure SNMP on the Cacti Server itself, including SNMPv3, as you will be spending a lot of time getting used to configuring Cacti, and making mistakes, so doing your initial setup and testing all on the local server is much simpler.
Once that's done, then set up MySQL for Cacti (Note: I am assuming you are conversant with basic MySQL setups under Mac OS X Server. If not, you'll want to spend some time on the MySQL web site, and Apple's documentation first. However, tackling that here is a bit out of scope for this article.):
- Create the user Cacti will access the database as. If the database server is on the same server as Cacti, then this user only needs access from localhost/127.0.0.1. If not, then limit the network access as much as possible.
- Create the Cacti database. You can name it whatever you want, but everything assumes you name it "Cacti" and if you get clever here, you'll be doing extra work forever. Clever should be saved for when you need it, and there's no reason to be clever here.
- Import the default Cacti database via the cacti.sql script in the root of the Cacti directory
- Give the Cacti user full rights to the Cacti database and only the Cacti database.
Next, set up the config.php file in $CACTIHOME$/include/config.php, so that Cacti knows what database on what server to use and has access to it.
Cacti Spine
Now, you'll want to install and set up Spine. Normally, Cacti's poller engine is a PHP process, and for light monitoring, that's fine. However, at some point, you can get to where the poller never finishes, because a scan takes longer than the polling period timeout. To help with that, you can optionally use Spine, which is a compiled poller engine written in C. It's a lot faster, but requires separate compilation and setup. The directions for its setup are solid, and it really does allow you to manage a lot more machines than the straight PHP poller.
Spine & SNMP on Mac OS X 10.5.7 Warning
If you read the notes on the security updates in 10.5.7, you'll notice that some SNMP libraries were changed. For the most part, this doesn't affect much of anything other than Spine. If you're trying to run Spine on 10.5.7, you will probably see, (up through version 0.8.7d, this is fixed in 0.8.7e and later) the following error:
SPINE: Poller[0] ERROR: SNMP Library Version Mismatch (5.4.1 vs 5.4.2.1) (Spine parent)
This is because Spine is very particular about versions and when they arent explicitly declared, things break. The workaround, until Spine changes how they do things, or whatever in netsnmplib 5.4.x isn't causing problems is to add the following line:
#define PACKAGE_VERSION "5.4.2.1"
to /usr/include/net-snmp/net-snmp-config.h, and then rebuild Spine. I did that, and it's been working fine ever since.
Apache
So we now have the Cacti side of things done, next, Apache. For Cacti to be able to work, you have to have PHP enabled and functional in Mac OS X Server. Cacti can't run without PHP. Period. For Mac OS X Server, you just create a site for Cacti, with the root of the site pointing to $CACTIHOME$. You'll want to make sure that index.php is a valid home page for the site, as that is Cacti's home page.
Initial Setup
So now, assuming you have everything set up correctly, load up Cacti's home page. The initial userid and password are both "admin", so you'll want to change those immediately. Cacti has a wizard of sorts, but that mostly is so you can set up the paths to things like the paths to rrdtool et al. (Shown in the screencap below.) Once that's done, you'll be at the base Cacti home page, and ready to do your initial setup.

Before we move on to the initial setup, let's look at the Cacti upgrade process, since it's pretty similar to the install.
Upgrade Notes
Because the basic Cacti install is not much beyond moving the new version to where the old version was, (assuming you aren't using plugins. Cacti plugins will of course, complicate this right up), building and installing a new version of Spine and pointing things to the new version, the upgrades are pretty simple. My method is:
- Download and unpack the new version of Cacti and Spine
- Copy the new version of Cacti, (not Spine), to the directory I keep Cacti in. (In my case, /usr/local/nagios/share) Don't rename the directory, keep the original name with version numbers.
- Make sure the permissions on the new version's directory are correct
- In the new version, set the database info in $CACTIHOME/include/config.php for the new version to match the info in the old version
- Copy the .rrd files from the $CACTIHOME/rra/ in the old version to the new version, watch their permissions
- Build and install Spine in its default location
- Copy the spine executable from the install location, /usr/local/spine/bin, to its working location, (this makes rebuilding, building new versions easier), after making a backup of the 'old' version of spine. For me, this is /usr/local/nagios/share/cacti_spine
- To be on the safe side, you should also do a backup of your MySQL DB. Sometimes new versions of Cacti change things, and if you don't back up your DB, rolling back could be hard, if you end up needing to.
- Point the 'cacti' symlink from the old version of Cacti to the new version of Cacti
- Log into the Cacti homepage, and let the upgrade wizard do its thing.
- Fire up the poller, (detailed later) and test. If something doesn't work, then you can usually roll back by pointing the symlink at the old version, and (if you have to), restoring the database from your backup.
(Note: We'll get to setting up the launchd job to run the Cacti Poller once we've gone over some of the basic setttings and setup.)
Settings
By default, Cacti is primarily an SNMP tool, so you'll need to have SNMP set up on the machines you want to monitor. However, instead of immediately creating devices, you'll want to spend some time in the settings. (This is assuming you made it through the first run setup script, which is pretty easy to deal with. You make sure the paths to things like snmpget, snmpbulkwalk, rrdtool, and php are set correctly, and you should be at the login page)
General Settings
This is where you set up things like logging, SNMP versions, RRDTool versions, and your SNMP defaults. That last bit is something you'll really want to pay attention to, as you'll save yourself a lot of really tedious work here. The SNMP Defaults section is where you set up the default SNMP v1/v2c & v3 defaults, along with the default version of SNMP to use. You can override this in the templates, and I'll show you that later on. (Templates are your life in Cacti. Time spent with them saves you GOBs of time later.) One warning is that Cacti displays the SNMP v3 Privacy Passphrase in plain text. So don't just let anyone in the settings page. Luckily, Cacti lets you create multiple levels of user.
Paths
Pretty obvious, this is where you set the paths to things. Normally, this is created on initial setup, so the only thing you'll normally have to add manually is the path to Spine, if you're using it.
Poller
This is where you'll probably spend the most time, settings-wise. If you are going to tweak the poller settings, either max number of processes, (cmd.php) or max threads/process, (spine), do so in small amounts, and monitor the results carefully. It's really easy to cause yourself a lot of pain if you get too radical with things.
In general, the big thing is to watch your Poller & Cron interval. If a complete polling takes longer than the allowed period, you can run into problems. So, you'll want to keep an eye on the log files, which will tell you how long things take. You can also run the poller manually, via php $CACTIHOME$/poller.php At the end of the run, Cacti prints timing info. Pay attention to that.
Authentication
While Cacti supports LDAP auth, I've not implemented that, since we don't have a lot of users, (really, only two categories: View Graphs Only, God. Keeps it simple), and I haven't had a need to change it. However, be careful here, authentication issues can make it not only hard to use Cacti, but can keep you from using it at all. In other words, don't be too clever.
User Management
Cacti gives you the ability to create multiple levels of users with really fine-tuned permissions. However, be careful, and don't create more classes of user than you have to. For my setup, I have two users. The administrator, who's god, and a "viewgraph" user, who can only view existing graphs, nothing more. So far that's worked well for me, but if you find yourself needing more, well, here's what you can do for user settings:

Realms settings

Graph permissions

Default graph settings
System Utilities
This is primarily for things like log access, cache access, etc. Cacti has a configurable logging level that can be invaluable when you're first getting used to the application, or troubleshooting errors, as you can set it to varying degrees of detail from "Yes, stuff happened", aka "Apple Release Note" to "here we see the interaction of quarks at the subatomic level". If you have a large number of users using Cacti, the User Log is handy for tracking user activity.
That takes care of the initial installation, and some of the settings. Next up...creating our graph trees and first devices!
| Comments ()September 19, 2009
A look at AppleScriptObjC
What AppleScript Programmers have been waiting for, even if they didn't know it: AppleScriptObjC
As some of you might know, AppleScript Studio, (Studio for short), never impressed me. To be blunt, I thought that it was a nice try that quickly showed itself to have gone down a bad path. The problem was that to do anything but a really narrow range of tasks (for Cocoa anyway), you had to use the "call method" command with a gob of 'real' Cocoa code, and if you're going to do that, why bother with Studio? The debugger was essentially unusable, and much of the time, just rebuilding a project with no code changes whatsoever would fail.
I have a real limit as to how much work I'll do to make up for a bad tool, and that's what Studio was...a bad tool with good intentions. Especially because I'd been spoiled by really good AppleScript tools like Script Debugger. Compared to Script Debugger, Studio lived down to its unfortunate acronym.
However, while no one was looking, Apple was listening. With Mac OS X 10.6, they released AppleScriptObjC, which is finally the product that Studio never could be: A real, first-class way to use AppleScript to create Cocoa applications. No more half-baked implementations or "oh, you need call method to do THAT" nonsense. Access to all the frameworks now, and in the future, the same way that Cocoa developers using Objective-C, Ruby, or Python get them...for free.
I'm not going to do a tutorial on AppleScriptObjC, because I'm still wrapping my head around it. If you want a tutorial, there's a good one at MacScripter. What I am going to do is do a light comparison between an AppleScriptObjC application, and the Objective-C version, then one between an AppleScriptObjC application and the Studio version. As you'll see, AppleScriptObjC is a win.
One of the things that AppleScriptObjC does is use AppleScript in a more "Cocoa-y" fashion. That is, Apple made the decision that for AppleScriptObjC, the way you use AppleScript should match the way you'd use other languages. There are obviously going to be significant differences between Objective-C, Ruby, Python, and AppleScript, but in general, Apple tried to make using AppleScriptObjC 'feel' as close to using any other language as possible. (There are more details on this in the AppleScriptObjC release notes I linked to.)
DotView
DotView is a simple application that draws a solid circle, or dot, in a window. You can move the dot around with the mouse, there's a slider to change the dot size, and a color control to change the dot's color. It's a simple application, and so is a good way to show the similarities between Objective-C in Cocoa and AppleScript in AppleScriptObjC.

Looking at the Objective-C version, there's not a lot of code. There's two .m files, DotView.m and main.m, and two header files, DotView.h and Preview.h. We'll focus on just the DotView.* files here, starting with the Objective-C version of DotView.h
<#import Cocoa/Cocoa.h>
@interface DotView : NSView {
NSPoint center;
NSColor *color;
CGFloat radius;
}
// Standard view create/free methods
- (id)initWithFrame:(NSRect)frame;
- (void)dealloc;
// Drawing
- (void)drawRect:(NSRect)rect;
- (BOOL)isOpaque;
// Event handling
- (void)mouseUp:(NSEvent *)event;
// Custom methods for actions this view implements
- (IBAction)setRadius:(id)sender;
- (IBAction)setColor:(id)sender;
@end
Not much really, about 14 lines of code that does the setup for things like setting the center, color, and radius of the dot, the functions for drawing the dot, and the functions for resizing and changing the color of the dot.
As far as the AppleScriptObjC version goes, there isn't one. AppleScript is a higher level language, and doesn't use header files. The AppleScriptObjC version still has to deal with the items that are in the Objective-C header file, but it will do so differently. (note that in this usage, "higher" is not a sign of superiority or inferiority. Instead, it denotes how "far from the hardware" a language lives. So AppleScript is a higher level language than Objective-C which is a higher level language than Assembly.)
What about the 'real' code? Well, here's the Objective-C DotView.m contents:
#import <Cocoa/Cocoa.h>
#import "DotView.h"
@implementation DotView
- (id)initWithFrame:(NSRect)frame {
[super initWithFrame:frame];
center.x = 50.0;
center.y = 50.0;
radius = 10.0;
color = [[NSColor redColor] retain];
return self;
}
- (void)dealloc {
[color release];
[super dealloc];
}
// drawRect: should be overridden in subclassers of NSView to do necessary
// drawing in order to recreate the the look of the view. It will be called
// to draw the whole view or parts of it (pay attention the rect argument);
// it will also be called during printing if your app is set up to print.
// In DotView we first clear the view to white, then draw the dot at its
// current location and size.
- (void)drawRect:(NSRect)rect {
NSRect dotRect;
[[NSColor whiteColor] set];
NSRectFill([self bounds]);
// Equiv to [[NSBezierPath bezierPathWithRect:[self bounds]] fill]
dotRect.origin.x = center.x - radius;
dotRect.origin.y = center.y - radius;
dotRect.size.width = 2 * radius;
dotRect.size.height = 2 * radius;
[color set];
[[NSBezierPath bezierPathWithOvalInRect:dotRect] fill];
}
- (BOOL)isOpaque {
return YES;
}
// Recommended way to handle events is to override NSResponder (superclass
// of NSView) methods in the NSView subclass. One such method is mouseUp:.
// These methods get the event as the argument. The event has the mouse
// location in window coordinates; use convertPoint:fromView: (with "nil"
// as the view argument) to convert this point to local view coordinates.
//
// Note that once we get the new center, we call setNeedsDisplay:YES to
// mark that the view needs to be redisplayed (which is done automatically
// by the AppKit).
- (void)mouseUp:(NSEvent *)event {
NSPoint eventLocation = [event locationInWindow];
center = [self convertPoint:eventLocation fromView:nil];
[self setNeedsDisplay:YES];
}
// setRadius: is an action method which lets you change the radius of the dot.
// We assume the sender is a control capable of returning a floating point
// number; so we ask for it's value, and mark the view as needing to be
// redisplayed. A possible optimization is to check to see if the old and
// new value is the same, and not do anything if so.
- (void)setRadius:(id)sender {
radius = [sender doubleValue];
[self setNeedsDisplay:YES];
}
// setColor: is an action method which lets you change the color of the dot.
// We assume the sender is a control capable of returning a color (NSColorWell
// can do this). We get the value, release the previous color, and mark the
// view as needing to be redisplayed. A possible optimization is to check to
// see if the old and new value is the same, and not do anything if so.
- (void)setColor:(id)sender {
[color autorelease];
color = [[sender color] retain];
[self setNeedsDisplay:YES];
}
@end
I left some of the functional comments in, so it's easier to see what the different parts of DotView.m are doing, but if you remove the comments and blank lines, the entire 'main' part of the application is only 47 lines of code. Admittedly, it doesn't do a lot, but still, that's not a lot. What about the AppleScriptObjC version? Here:
property NSColor : class "NSColor"
property NSBezierPath : class "NSBezierPath"
script DotView
property parent : class "NSView"
property |center| : {x:0.0, y:0.0}
property radius : 0.0
property |color| : missing value
on initWithFrame_(frame)
continue initWithFrame_(frame)
set my |center|'s x to 50.0
set my |center|'s y to 50.0
set my radius to 10.0
set my |color| to NSColor's redColor()
return me
end initWithFrame_
on drawRect_(rect)
NSColor's whiteColor()'s |set|()
tell NSBezierPath's bezierPathWithRect_(my |bounds|()) to fill()
set origin to {(my |center|'s x) - (my radius), (my |center|'s y) - (my radius)}
set |size| to {2 * (my radius), 2 * (my radius)}
my |color|'s |set|()
tell NSBezierPath's bezierPathWithOvalInRect_({origin, |size|}) to fill()
end drawRect_
on isOpaque()
return true
end isOpaque
on mouseUp_(|event|)
set eventLocation to |event|'s locationInWindow()
set my |center| to my convertPoint_fromView_(eventLocation, missing value)
tell me to setNeedsDisplay_(true)
end mouseUp_
on setRadius_(sender)
set radius to sender's doubleValue()
tell me to setNeedsDisplay_(true)
end setRadius_
on setColor_(sender)
set my |color| to sender's |color|()
tell me to setNeedsDisplay_(true)
end setColor_
end script
This does the same thing as the Objective-C version, but in about 40 lines of code. If that doesn't make any sense, this is where AppleScript being a higher level language has its advantages. Because the AppleScript runtime, (the component that executes all AppleScript code), handles things like memory management for you, you don't have to write code to deal with de-allocating memory you allocated earlier. However, there's a price to be paid for this convenience, and that's usually in size, (all things being equal, an application written in an interpreted language like AppleScript tends to be larger, and need more memory than an application written in a compiled language like Objective-C), and speed, (interpreted languages tend to be slower than compiled ones). But, for code that really doesn't care about either, the difference is a wash, and is up to programmer preferences/job requirements.
The thing I wanted you to initially see, is that unlike Studio, which as we'll see, has a syntax implementation that "verbose" doesn't even begin to cover, AppleScriptObjC lets you get work done without having to bang out gobs of code for even simple things. The next thing we want to look at is the way that AppleScriptObjC and Objective-C have similar structure, even though the languages themselves are quite different. For example, let's look at setting up the variables for drawing the dot. To draw a solid colored circle, you need three basic bits of information:
- You need the center of the circle, so you know where to start
- You need the radius of the circle, so you know how big the circle will be
- You need the color of the circle, so you know what color to use to draw and fill in the circle.
In the Objective-C version, this is done in the header, (.h) file with this code:
@interface DotView : NSView {
NSPoint center;
NSColor *color;
CGFloat radius;
}
The code is using features of the NSView class to create three things:
- An NSPoint variable, center
- An NS color variable, *color
- A CGFloat variable, radius
Those will be used in the DotView main code to tell the application what the center, color, and radius of the circle should be so it can be drawn correctly. Now, the AppleScriptObjC version:
property parent : class "NSView"
property |center| : {x:0.0, y:0.0}
property radius : 0.0
property |color| : missing value
The syntax is different, but still similar. We tell the script to use the features of NSView to create the same three variables: center, radius, and color. With AppleScriptObjC, we also have to set the initial values for the variables, whereas we didn't in Objective-C, but that's a syntax difference. The reason that AppleScriptObjC's center and radius variable names have vertical bars around them is because those particular words are normally reserved by AppleScript. The vertical bars tell the AppleScript runtime "Hey, for this application, use these variables the way I'm defining them here, not the way you normally would use them." In talking with some of the AppleScript team at Apple, they told me that the bars themselves are harmless. If you accidentally put them in where they aren't needed, no harm no foul, it shouldn't affect anything adversely. The reason that color is defined to be a missing variable is because its value will be set by a UI control, and so this is how AppleScriptObjC lets you reserve variables that you're going to "hook up" to the UI in your application.
The important point is, if you were to have never coded in anything but Objective-C in your life, and suddenly had to look at the AppleScriptObjC version of some Objective-C code, you'd have a far easier time of correctly interpreting what the code was doing than you'd ever have with Studio. Here, let's look at one more example. This time, we'll look at the code that creates the initial dot on application launch. First, the Objective-C code:
- (id)initWithFrame:(NSRect)frame {
[super initWithFrame:frame];
center.x = 50.0;
center.y = 50.0;
radius = 10.0;
color = [[NSColor redColor] retain];
return self;
}
Now the AppleScriptObjC code:
on initWithFrame_(frame)
continue initWithFrame_(frame)
set my |center|'s x to 50.0
set my |center|'s y to 50.0
set my radius to 10.0
set my |color| to NSColor's redColor()
return me
end initWithFrame_
The AppleScriptObjC code's a bit more verbose, but still, the similarities are undeniable. Thanks to the work the AppleScript team did to make AppleScript syntax work the way 'normal' Cocoa application syntax works, it is much, much easier to move between Objective-C and AppleScriptObjC's 'flavor' of AppleScript than it ever was to move between Objective-C and Studio's 'flavor' of AppleScript.
The advantages to this aren't just in more efficient code, or fewer lines. One big advantage to this similarity is that an AppleScriptObjC programmer can read the 'normal' Cocoa documentation far easier than a Studio programmer can, because the way you use the language now follows the 'correct' Cocoa methods more closely. So rather than having to recreate the entire Cocoa documentation set for AppleScriptObjC, the AppleScript team can create a smaller set of core AppleScriptObjC documentation to help you get started, and then you can use the normal Cocoa docs for everything else. That's a huge advantage.
But what about AppleScriptObjC and Studio? How does AppleScriptObjC compare to Studio? Quite favorably as it turns out. By 'quite favorably' I mean "leaves Studio in the dust, choking and wondering why those durn kids knocked its walker over". First, with Studio, you only had access to the parts of Cocoa that Studio explicitly knew about. If Apple introduced a new framework, you couldn't just use that in Studio, you had to wait for the Studio team to implement it. With AppleScriptObjC, there's none of that. AppleScriptObjC is able to use new frameworks and features as soon as they show up in the OS. Now, you could work around that limitation in Studio via the infamous "call method" which let you shell out to 'real' Cocoa code in the Studio application. It turns out, you did that a lot in a Studio application, to where a lot of people just gave in and learned Objective-C.
Task List
So from a feature standpoint, it's not even close. AppleScriptObjC wins easily over Studio. What about a code comparison? Unfortunately, I couldn't find a Studio version of DotView, but I did find another simple application that has both Studio and AppleScriptObjC versions: Task List. Task List is just what it sounds like: a simple application that lets you create and manage a list of tasks/to-dos

A nice simple application, so the comparison, as with DotView, will be simple. So, first, the AppleScriptObjC version:
script Task_ListAppDelegate
property tableData : {}
property removedTableData : {}
property tableDataController : missing value
property CalCalendarStore : class "CalCalendarStore"
property NSMutableArray : class "NSMutableArray"
property CalTaskClass : class "CalTask"
on awakeFromNib()
set removedTableData to NSMutableArray's array()
set tableData to NSMutableArray's array()
syncTaskList()
end awakeFromNib
on applicationWillTerminate_(application)
syncTaskList()
end applicationWillTerminate_
on applicationWillResignActive_(application)
syncTaskList()
end applicationWillResignActive_
on applicationWillBecomeActive_(application)
syncTaskList()
end applicationWillBecomeActive_
on addTask_(sender)
tableDataController's addObject_({priority:"3", task:"", status:"Not Started", calTask:missing value})
end addTask_
on removeTask_(sender)
set deleted_objects to tableDataController's selectedObjects
set deleted_object to item 1 of deleted_objects
removedTableData's addObject_(deleted_object)
tableDataController's remove_(missing value)
end removeTask_
on syncTaskList()
set calendarStore to CalCalendarStore's defaultCalendarStore
set theCalendars to calendarStore's calendars
set todoPredicate to CalCalendarStore's taskPredicateWithCalendars_(theCalendars)
set tasksInCalStore to CalCalendarStore's defaultCalendarStore's tasksWithPredicate_(todoPredicate)
set tasksInTable to tableData's valueForKey_("calTask")
set tasksToDelete to removedTableData's valueForKey_("calTask")
set tasksAdded to NSMutableArray's array()
-- Get tasks from iCal that aren't in the table, and delete tasks from iCal that we've been asked to kill
repeat with aTask in tasksInCalStore
if not (tasksInTable's containsObject_(aTask) as boolean) and not (tasksToDelete's containsObject_(aTask) as boolean) then
-- Add a new task if it's not in the list of showing or deleted taks
set priority to aTask's priority as string
set |title| to aTask's |title| as string
tableDataController's addObject_({priority:priority, task:|title|, |status|:"Not started", calTask:aTask})
tell tasksAdded to addObject_(aTask)
else if tasksToDelete's containsObject_(aTask) as boolean then
-- Delete task we were asked to kill
set returnValue to calendarStore's removeTask_error_(aTask, reference)
if not item 1 of returnValue then
set err to item 2 of returnValue
error (err's localizedDescription())
end if
end if
end repeat
-- Update and create new calTasks based on table data
repeat with tableDataItem in tableData
set calTable to tableDataItem as record
try
set aCalTask to calTable's calTask
on error
set aCalTask to missing value
end try
if aCalTask is not equal to missing value and not (tasksInCalStore's containsObject_(aCalTask) as boolean) and not tasksAdded's containsObject_(aCalTask) as boolean then
-- Delete this task, which was deleted in iCal
tell tableDataController to removeObject_(tableDataItem)
exit repeat
else if aCalTask is equal to missing value then
-- Create new CalTask for a newly created table row
set aCalTask to CalTaskClass's task()
set aCalTask's calendar to (get first item of calendarStore's calendars)
set the calTask of tableDataItem to aCalTask
end if
-- Save out both the existing tasks and freshly created tasks
if aCalTask is not equal to missing value then
set the |title| of aCalTask to tableDataItem's task
set the priority of aCalTask to (tableDataItem's priority's integerValue)
set returnValue to calendarStore's saveTask_error_(aCalTask, missing value)
end if
end repeat
end syncTaskList
end script
That's not bad, about 73 lines of code, if you remove non-code lines. What about the Studio version? I'm not pasting it in here, because it's about 185 lines of code or so to do the same thing. Well, less, as we'll see in a bit. So let's look at some common code here, the "awake from nib" function, which is analogous to the application launch. The AppleScriptObjC version:
on awakeFromNib()
set removedTableData to NSMutableArray's array()
set tableData to NSMutableArray's array()
syncTaskList()
end awakeFromNib
That's pretty simple. Set a couple variables to arrays, and run something called syncTaskList. The Studio version:
on awake from nib theObject
if name of theObject is "tasks" then
-- Create the data source for our "tasks" table view
set theDataSource to make new data source at end of data sources with properties {name:"tasks"}
-- Create the data columns, "priority", "task" and "status". We also set the sort properties of each of the data columns, including the sort order, the type of data in each column and what type of sensitivity to use.
make new data column at end of data columns of theDataSource with properties {name:"priority", sort order:ascending, sort type:numerical, sort case sensitivity:case sensitive}
make new data column at end of data columns of theDataSource with properties {name:"task", sort order:ascending, sort type:alphabetical, sort case sensitivity:case sensitive}
make new data column at end of data columns of theDataSource with properties {name:"status", sort order:ascending, sort type:alphabetical, sort case sensitivity:case sensitive}
-- Set the data source as sorted
set sorted of theDataSource to true
-- Set the "priority" data column as the sort column
set sort column of theDataSource to data column "priority" of theDataSource
-- Finally, assign the data source of the table view to our data source
set data source of theObject to theDataSource
end if
end awake from nib
Oof. Even if I were to take the comments out, we can still see that the Studio version is a lot bigger, and seems to require you to do a lot more work for the initial application setup. That's because it does require more work for initial application setup. Even though you use Interface Builder to build the UI elements for both AppleScriptObjC and Studio, AppleScriptObjC is able to use things the way a 'real' Cocoa application does. So unlike Studio which makes you create manually create the AppleScript implementation of the data columns that will be used by the UI, and set all the properties of those data columns, AppleScriptObjC is able to use the information that you already put into Interface Builder, and that Interface Builder provides for free. The idea behind this is trick called "bindings". I'm not going to even try to explain bindings here, but they're what allow AppleScriptObjC to not have to need all the code that Studio needs. It's not that the UI in Studio doesn't have all the bindings info available to it, it's that bindings are invisible to Studio, and so with Studio, you're stuck using the older Data Source API. So, in a sense, even though you've built the UI in Interface Builder, you have to do a lot of redundant work in Studio to manually define what the UI elements in Task List are doing, work you don't have to do in AppleScriptObjC.
That's kind of the idea with Interface Builder, by the way. You create the UI elements, set them up, and then the code is able to just use them.
While Studio's use of AppleScript is more 'traditional', it's also far kludgier. This is repeated over and over throughout the code. Stuff that AppleScriptObjC can do in a few lines, Studio takes a book. Stuff that AppleScriptObjC doesn't even need code for, Studio needs lines and lines and lines.
Oh, and the syntax is so far removed from 'normal' Cocoa syntax, even allowing for specific language differences that there's almost no way to apply standard Cocoa documentation and sample code to Studio. The gulf between them is just too wide.
However, I do feel that I should come clean about something. When I said that AppleScriptObjC took about 73 lines of code to do the same thing that Studio needs almost 200 lines of code to do, I was lying. Blatantly lying. It really only needed 24 lines of code to do what Studio did. The other 49 or so lines of code let you integrate Task List into the iCal store, so you can see your iCal tasks in Task List, and have the tasks you add to Task List show up in iCal. I don't even want to think about what it would take to do that with Studio, assuming you even could without having to use "call method" and shell out to 'real' Cocoa code. However, AppleScriptObjC does lose to Studio in one important way: AppleScriptObjC and AppleScriptObjC applications will only run on Mac OS X 10.6 or later. If you want to create applications using AppleScript for Mac OS X 10.5 or earlier, you cannot use AppleScriptObjC.
AppleScriptObjC is a huge change, and it does bring with it a lot of new things you'll need to learn, and unlearn, especially if you are using Studio. But, it is also a huge leap forward in capability and features for AppleScript. It also shows, better than any amount of platitudes could, that AppleScript is not going away anytime soon. I just cannot see Apple doing this much work, and creating such a monstrously huge improvement to AppleScript just to knife it.
September 14, 2009
It's still not the language's fault.
From the new Acorn 2.0 release notes:
I actually came up with JSTalk specifically for Acorn. I was looking at adding AppleScript support to Acorn, since scriptibility was a big feature request, but I've always found AppleScript to be too cumbersome. And I hate writing examples in AppleScript, so JSTalk it is.
That sound was my interest in the product fading away. Not because I hate Javascript, even though I do. Because sometimes, JS is the best tool for the job, and you use it anyway. But because Apple does make creating an language-neutral scripting interface doable, (dude, it's a 10.6 only application, so screw legacy support, there is none, and besides, in 10.6, AppleScriptObjC really does put AppleScript on the same level as Ruby and Python), and there are hundreds of people who if you ask, and maybe throw in a license or two of Acorn and a thank you, will write your examples for you.
Secondly, if you're going to rag on AppleScript because it's "too cumbersome", then don't have shit like this on your jstalk sample page:
Give me an example Here's an AppleScript example, for adding a new rectangle object to a sketch document:tell application "Sketch"
tell document 1
set o to make new box
set width of o to 100
set height of o to 100
set stroke thickness of o to 10
end tell
end tellAnd here's how you do it with JSTalk, using a doctored version of Sketch (6 lines of code, + the JSTalk framework):
var sketch = [JSTalk application:"Sketch"];
var doc = [sketch orderedDocuments][0]
var rectangle = [doc makeNewBox];[rectangle setWidth:100];
[rectangle setHeight:100];[rectangle setXPosition:100];
[rectangle setYPosition:100];If you aren't a fan of the optional bracket syntax, you can also write the script this way:
var sketch = JSTalk.application_("Sketch");
var doc = sketch.orderedDocuments()[0]
var rectangle = doc.makeNewBox();rectangle.setWidth_(100);
rectangle.setHeight_(100);
rectangle.setXPosition_(100);
rectangle.setYPosition_(100);
if there's some fucking magic here that makes "set o to make new box" less cumbersome than "var rectangle = doc.makeNewBox();" or "var rectangle = doc.makeNewBox();", I'm totally missing it.
Note that the example AppleScript Gus shows is actually more cumbersome than it needs to be, because the way to do this is to make width, height, stroke, xPos, and yPos properties of box, so you could do it as:
set o to make new box with properties {height:100, width:100, xPos:100, yPos:100, stroke:10}
Yep, that's so cumbersome.
But like computers, programming languages all suck anyway. The ones you like? They suck. The ones I like? They suck too. If however, they suck the right way, and you can wrap your head around them, then you can use them. But they still suck.
As to Gus disliking AppleScript, he must really dislike it. There's nary a post on either AppleScript-Implementors or AppleScript users asking either for tips in implementing a dictionary, or help with examples. Kind of hard to get help when you never ask for any. Funny how that works.
As well, Gus seems to either miss, or not care that he's kind of cutting Acorn off from the larger Mac OS scripting community. Because by writing a language-specific scripting implementation, now, if you want to have scripts that say, shove data into or get data out of Acorn, you have to either do all the bridge work to JSTalk yourself, or, you have to start writing Objective C code:
But no apps out there currently support JSTalk! Applications can also be scripted using Cocoa's Script Bridge class, SBApplication. Here's an example:[[SBApplication application:"iChat"] setStatusMessage:"Happy (funball)"];
Although this is great to have, it's not the same as an application natively support JSTalk over DO. Anything more than simple tasks using SBApplication tends to be a little more than difficult.
No kidding. Again, let's see how cumbersome this would be in AppleScript:
tell application "iChat" to set status message to "not that hard after all"
Wow. That's pretty cumbersome. Thank God we have a way to avoid such onerous syntax.
Yes, I know, the snark is cranked, but too bad. If Gus felt that writing his own language-specific scripting implementations was the best way to go, fine, then say that. See, it's easy:
"For Acorn, none of the existing scripting implementations did what I wanted, so I rolled my own." See? Easy, and you're standing on your own two feet. But don't hide behind some bullshit like "I hate writing AppleScript sample code" when as near as I can tell, (based on searching for Acorn, Gus, Mueller, or Gus Mueller), you never even bloody looked into it because of your feelings towards AppleScript. Given the way you write AppleScript examples, I don't see a lot of experience with the language.
That's not AppleScript's fault, that's your goddamned decision all on its own, so put your fucking big boy pants on and stop letting others be your fall guy.
| Comments ()September 8, 2009
Dildo has issues
Serious issues. So of course, Dildo reprints his AppleInsider article on his little "I blow Steve Jobs for candy" site, (he's still got factual errors in the stupid thing, even though after being slapped around, he finally did some research about what the MacBU is actually doing) and things being what they are, someone asks him about my...takedown. His response is a priceless bit of ad hominem:
John C. Welch’s Bynkii.com is a strange place. He fantasizes about raping women he finds “too stupid,” talks about “skull f*cking” people who he feels have made mistakes, and so on. It’s a really weird exposure of his angry and apparently sexually frustrated world.
Le Sigh. You write one article about flash-mob-bukakke, and you're fantasizing about raping women. I'm once again going to guess that people like George Carlin and Richard Pryor never existed in Dildo's world, because honestly, I'm kinda tame in comparison. But, if you use the right words with someone, you can get people to think all kinds of things. So, by allllmost accusing me of being a closet rapist, or what have you, (a closet skull-fucker? Did this idiot never see "Officer and a Gentleman"?). Of course, Dildo has to come up with a reason as to why I would say such things, (if you think of someone getting the vapors it helps). Since it can't just be for comedic effect, (what's that?), I must be sexually frustrated.
It's a great accusation. No, seriously, it's right up there with "are you still beating your wife". I don't know if there's a pithy latin phrase for it, but basically, if you accuse someone of it, there's no way for them to defend themselves. I mean, how do you prove such a thing? Nail a sorority in front of them? That just proves it more, obviously, if you weren't, you wouldn't need to do such a thing. The only thing you can do is kind of laugh, because it's also a 12-year old tactic. I'm surprised Dildo didn't pull "your mom's a whore" out too, it's at the same level, and about the same maturity level.
Also, having had Dildo get his vas in a twist about me more than once, he always, always, always, brings up violent sexual imagery for his ad hominems. Maybe Dildo's projecting just a wee bit? (I'll admit it, being immature sometimes is fun.)
Of all of the many trolls who have a problem with me, John C. Welch is the one I have the least interest in responding to. He apparently thinks he’s being funny, but in reality he just spends lots of time (it’s a lot of work to write paragraphs of text, check for grammar, etc) trying to run people down rather than correcting anything or actually printing anything of use to others. And he calls me the douche bag? Hilarious.
Of course. Dildo's never committed a technical, factual, error in one of his asinine posts. Nor has he ever defended technical, factual errors in any of his articles as being unimportant for n00bs.
Of course facts don't matter to Dildo. What he's running is a vaguely technical version of "The National Enquirer", and knows that his fanbase doesn't give a dead rat for facts. They just want moar MacMac! Hey, if it works, booyah, but don't get all butthurt when people point them out to you. Note: even if someone points out and proves a factual error in a rude fashion, they've still busted you in a mistake. Maybe you should try fact-checking more. (I know, I know, Dildo and facts.)
I hope he never has to go looking for work, because a potential employer who ran across his site would never hire him. Every sentence on his site is dripping with sexualized frustration and rage, written like a child molester psychopath with his balls nailed to the floor.
BRING OUT YOUR CONCERN TROLLS! BRING OUT YOUR CONCERN TROLLS!
Let's be clear here, Dildo is out and out lying in this one. The little weasel would love nothing better than if I were penniless and on the street. Oh, he might even say some nice words about "his poor family, suffering for his mistakes", but at the end of the day, he'd be in his mom's basement cackling with joy. It's okay Dildo, everyone loves schadenfruede. It's your dishonesty about it all that's lame.
As well, where the fuck does this idea that somehow, I hide this site from my employers come from? Because I don't. Every employer I've had since I started this site knows about it. In fact, (hold on to your tea towel Dildo, this one's gonna give you the vapors for sure), I want them to know about it. I don't like playing games with people, or surprising them. Surprises make for bad IT, and games suck. I don't specifically talk about my job here, but that's more because if I start using their name here on a regular basis, then disclaimer or no, this site becomes a de facto "spokessite" for them, and that's not the point of this site. I don't want it to be a "spokessite" for anything but my stream of consciousness at that moment. I also have a habit of not publicly criticizing people I work for. I do that in person like a grownup. I guess in Dildo's world, passive-aggressive rules uber alles.
What Dildo doesn't seem to get is that there are employers, (and I appreciate them all), who understand that their people are not clones, and may in fact have opinions they dislike. They may even express them in ways they don't like. That doesn't mean they aren't good people. It just means that sometimes, your IT guy is a fucking big-mouthed smartass. Whatever.
But again, did you see that imagery?
Every sentence on his site is dripping with sexualized frustration and rage, written like a child molester psychopath with his balls nailed to the floor.
Someone has serious sexual issues, but it sure as shit ain't me.
Oh, and did you notice, he never addressed any of the actual errors I pointed out. Yeah, Dildo's like that.
Technorati Tags:
New Media Douchebags
| Comments ()
September 5, 2009
it's not your fault
So with the current Wordpress vulnerability and attacks, I see a lot of people who seem to be blaming themselves for not 'doing more' to have prevented getting attacked.
"I should have been more paranoid about security"
"I should have had better backups"
"I should have patched immediately"
From me, to all of you, including Robert Scoble and Andy Ihnatko: Shut up. You're wrong.
Let me explain. While things like being more on top of patches, thinking more about security, and better backups are good,
(although backups are not a security issue as much as a "shit breaks" issue), the fact you got broken into is.not.your.fault.
Even if you were way behind in patching, and your administrator password was "password", it's not your fault. Some fucking douchebag who should have sluiced down their mother's gullet with their 23452345 other loser siblings broke into your shit, and fucked it up. It is their fault. It is not Wordpress's fault either. Wordpress did not take the time to break into your stuff. The only, only blame here belongs, 100%, period, end of statement, to the dickwhip that attacked your site.
Y'all are the victims of this, and rather than blaming yourselves, you should be angry. You should be white-hot balls of fucking angry fire, and you should be on the fucking phone to the fucking FBI and letting them do some forensic analysis so the shitheads who did this might one day be locked in a soundproof, windowless room with a 6'8" serial killer with a huge cock and a skull-fucking fetish.
If there is one thing about geeks that fucking pisses me off, more than Enderle, Thurrot, and all the other NMDs combined it is this...blame the victim mentality. This idea that if you aren't locking your site down tighter than Fort-fucking-Knox, you deserve to be attacked. It's exactly the same as blaming a woman for getting raped because she wasn't dressed like a nun and living with her parents, or blaming someone for getting mugged because they know that part of town is bad, or blaming James Byrd for getting dragged to death by three racist assholes because he should have known better than to get a ride from three racist shitheads. If someone breaks into your web site, your email server, your file server, it is their fault. It is their fault if you have no security, it is their fault if you have fucking stellar security, it is always, always, always their fault.
You weren't being a tease, lookin' all sexy at them with your data right there for the taking. They did not have to fuck with your stuff. They chose to do that. It is their fault. Period. The way I see people blaming themselves for this makes me want to vomit, then ask them if they think that women who get drunk at a party deserve to be gang-raped.
If someone breaks into your site, it is not your fault. There is no room for argument on this, don't even attempt to justify this to me.
Not.Your.Fault.
| Comments ()Douchebags fondly eviscerated
Normally, i ignore Daniel Eran DildoDliger, because not only is the boy the living embodiment of Artie MacStrawman, but face it...he's just a fucking dumbass. Constantly. Consistently. Dumb. Ass.
Take his latest shitpile on AppleInsider: Inside Mac OS X Snow Leopard: Exchange Support. I have not seen something that wrong since I had to eat Keilbasa with Cool-Whip as dip.
Integrated support for Exchange beginning with last year's iPhone 2.0 means Apple's mobile platform simply doesn't need an Outlook client. Now Snow Leopard can also get by without Entourage/Outlook, thanks to new and improved baked-in support for Exchange in Mail, Address Book and iCal.
Dildo is of course making the classic MacMac dumbass argument:any Exchange support Apple provides is all the support you need. This of course, is idiotic. While I'm quite sure that Apple handles the basics well enough, it's not going to match even Entourage's feature set, much less the featureset of an application no one knows about, namely Outlook. Yet, in true MacMac fashion, Daniel knows, KNOWS that Apple's Exchange support is all you need.
With iWork and the built in Exchange client support in Snow Leopard, many users will have no need to even consider Microsoft's Mac client offerings. It will be very difficult for Microsoft to convince Mac users that they need Office after those users discover suitable alternatives that cost significantly less
Dildo has a rare good point here. Microsoft does have a problem getting people to pay for Office for home/soho use. However, in the enterprise, the story's a bit different, since what you pay for Office with an Enterprise Agreement is significantly less than you pay for Office retail. Also, if your company, like many who use Microsoft backends, is using things like Sharepoint, then the cost of Apple's offerings is rather meaningless: you'll need more than they can provide.
With Snow Leopard and the iPhone each now providing their own client layer for accessing Exchange Server, Apple can now offer its users alternative access to other server products as well, from its own MobileMe and Snow Leopard Server offerings to web services from Google and Yahoo. This effectively turns Microsoft from a direct seller into a wholesaler that has to deal with Apple as a middleman retailer.
Disappointingly, but predictably, Dildo veers from "good point land" back into MacMac Dumbassville at high speeds. Out of all the vendors he lists, only Google is actually a competitor for Microsoft in the groupware arena. Mobileme as an Exchange competitor? You'd have to be smoking hobo crack, (as in "ass" not "rock") to say that without snickering. As well, the fact that the iPhone can talk to Exchange via EAS, (Exchange Active Sync, an Microsoft technology that Apple licenses from Microsoft. I guess Dildo conveniently forgets this), or that Mac OS X 10.6 can talk to Exchange via Exchange Web Services (another Microsoft tech), has nothing to do with the fact that Apple provides other ways to talk to other services. For one, you can't use CalDAV with Exchange anyway, unless you use some unsupported connector. As far as the "turning Microsoft into a wholesaler" shit...fuck dude, beats me, maybe the speckled pills were kicking in?
Ten years ago, Apple was in that position with its hardware sales. It tried hard to get Sears, CompUSA and other retailers to sell Macs for it, but those retailers also sold generic PCs. Because they made more money selling generic PCs, they had little incentive to aggressively market Macs. Apple's retail stores eventually solved this issue by allowing the company to reach users directly.
Note: this is a non-sequiter, but with Dildo, (yeah, that's my new name for him. Makes him sound like the fucked-up hobbit that no one would play with. The one that sits in the corner, eating lice out of his foot hair) loves to bring shit like this up. He still can't accept that the 'bad old days' are over a decade gone. He also forgets that Apple is gradually reintroducing Macs back into other retail environments, like Best Buy. But then, Dildo's a dumbass.
As Apple takes over the client end of Exchange, it similarly gains market leverage. First and foremost, the move allows Apple to improve the Exchange experience of Mac users so that business users have no reason not to buy Macs. Secondly, it gives Apple a client audience to market its own server solutions, including MobileMe to individual users and Snow Leopard Server to organizations. In concert with providing Exchange Server support, Apple is also delivering integrated support for its own Exchange alternatives in both MobileMe and with Snow Leopard Server's improved Dovecot email services, Address Book Server, iCal Server, the new Mobile Access secure gateway, and its included Push Notification Server.
MOBILEME IS NOT AN EXCHANGE REPLACEMENT YOU FUCKING IDIOT.
Jesus, has this fuckwit ever USED Exchange? I mean in the last ten years? Saying MobileMe is a viable alternative to Exchange is like saying that a fucking Chevy K car is a viable alternative to a Kenworth Semi, because they're both vehicles. Secondly, you waste of colon, "Dovecot email services" literally makes no fucking sense. There's no email service called "Dovecot". Do you have a Dovecot client? A Dovecot protocol? No. You can have a Dovecot-based email server that provides POP/IMAP/SMTP email services, but there's no fucking such thing as Dovecot email services. Secondly, Mobile Access Gateway is not a fucking Exchange anything, it's a fucking reverse SSL proxy. A security appliance, not a groupware server. Address Book Server? Neat idea, but it's a fucking 1.0 product based on a pre-standard draft, and there's no one making clients yet except for Apple, and maybe Oracle. What are the windows users supposed to do? Oh wait, no one uses Windows once you bring a Mac in the door, because they're fucking magic. Push Notification Server? Goddamnit, where's my fucking Cockpunch over IP client?
But none of this, none of this compares to the sheer idiocy that follows:
Apple's support for Exchange and its promotion of its own Exchange alternatives are two sides of the same coin, in the sense that they use the same technologies. Apple built its support for Exchange using WebDAV, the open specification that Microsoft supports on Exchange Server as a way to deliver messages to mobile clients. Apple did not license Microsoft's Windows-only "Exchange Active Sync" software; it merely licensed the rights to implement a compatible EAS conduit with Exchange. Apple owns the Snow Leopard software that talks to Exchange.The client applications Apple has upgraded in Snow Leopard to connect to Exchange, including Mail, Address Book, and iCal, also use WebDAV to talk to Apple's own Snow Leopard Server applications. Because Apple makes its money almost exclusively from selling hardware, it has opened up its own Snow Leopard Server applications, Address Book Server and iCal Server, as open source Darwin servers that can be compiled to run on Linux. That means Apple is essentially giving away both the client (to Mac users) and the servers (to the community) in order to encourage the use of open standards in messaging and collaboration. That giveaway is being done to help Apple sell Macs.
This effort to support everything from integrated client software owned by Apple makes Snow Leopard's support for Exchange of use to everyone, even if they don't use Exchange. The client work Apple has invested in making Macs Exchange-friendly also improves the features available via MobileMe, Snow Leopard Server, and even some other third party services such as those from Google and Yahoo.
There is nothing, literally nothing about those paragraphs that makes any fucking sense, and it shows that Daniel doesn't know a fucking thing about what he's blathering about. First, no, Apple is not using either WebDAV or HTTP-DAV, (the correct term for the protocol he got wrong), to talk to Exchange. For the Exchange connectivity in Mac OS X 10.6, Apple is using Exchange Web Services, or EWS for short to talk to Exchange. EWS is the protocol that is not only replacing DAV, but MAPI as well, and I'm almost surprised he didn't say that Apple was using MAPI. In fact, the use of EWS is why you can only use Mac OS X 10.6's Exchange support with Exchange 2007 or later, because earlier versions don't support EWS. Ironically, if Apple was using DAV, they'd be able to talk to Exchange 2003 or 2000, because those version support DAV too!
Secondly, no, Apple didn't license EAS for Mac OS X 10.6, it licensed it for the fucking iPhone. Apple wouldn't use EAS for Mac OS X 10.6, because EAS is designed for mobile devices. As well, you waste of fucking carbon, EAS is not windows-fucking-only. It's used on pretty much every smartphone on the planet, and by quite a few groupware servers on Linux and Mac OS X. In fact, at my "real" job, we use EAS to connect iPhones to Kerio Mail Server running on Mac OS X! So no you dickwipe, Apple doesn't own all the software that they use to talk to Exchange, or Exchange-like servers.
Fourthly, Apple's implementation of EWS on its client software has nothing to do with the services provided by its server software, and it has even less to do with MobileMe, (what the FUCK is it with Dildo and MobileMe), Google or Yahoo. Apple's server products don't provide EWS for clients, and you can't use EWS to connect to Google or Yahoo, because they don't use EWS either.
I've seen more intelligent things written by diarrhetic gibbons in their own shit than this fucking tripe.
The last three paragraphs continue this line of shit so badly that I can't even bring myself to go into details.
Oh, and I see Daniel wrote a book on Mac OS X Server. Quite honestly, if you're buying books on technical matters written by Dildo, save some money and just ask the fucking cat. You'll get an answer of equal quality, only from a more authoritative source.
Technorati Tags:
New Media Douchebags
| Comments ()
September 1, 2009
Best unintentionally funny comment ever.
From Metafilter:
"In summary: John C Welch probably thinks Lotus Notes is a really great email program."
BAAAAHAAHAHAHAHAHAHAHAHAAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAH
"D'ja ever notice, on the internet, people say things they wouldn't say to each others faces? From the comments:
"Good article but honestly fix your CSS. The article was great before I moved past the fold. Is repeat so hard to spell out in code?"
"...So if you have a better way to word a background-repeat statement, by all means share, i'll be happy to fix it if I buggered the syntax. Otherwise, fucking off would be a good option."
He don't know me vewwy well, do he.
Rob wants to play
You know, I always love when someone quote mines a post of mine to make a dubious point, along with the invoking of strawmen et al. I love it even more when that person does so in a blog post that doesn't allow comments. I love it even FURTHER when a "researcher" is doing the quote mining, considering how much that crowd hates it when it's done to them.
Enter Rob Shearer, and his dramatic post: Our IT Overlords
Rob of course, doesn't waste any time. Here's his second paragraph:
My only real quibble with Manjoo’s article is that “modern” companies have already recognized this; it’s only the crusty behemoths whose IT departments have decades of legacy policy that continue to treat users like infants. Of course, such behemoths still represent a huge fraction of the economy and the work force, so his point stands. Some people don’t realize that IT has moved on since the 80s.
You know, I hear a lot about these remaining behemoths, but in almost every case where they bother to provide things like actual examples, it turns out to be a bit different. Note that Rob never bothers to provide any examples, just the usual canards about people not realizing that IT has moved on since the 80s.
Yes Rob. There are hosts of IT departments still handing out IBM PCs with 5.25" Floppy Drives that only run 33270 emulators. Oh wait, there aren't, at least not in the US, and I'll hazard, in the UK. But again, standard "I hate IT screed" pt. 345
Paragraph 3 leads into the massive quote-mining, (shame on you Rob, quote mining is for fundie creationist idiots, not someone trying to get a Ph.D in CompSci. You should know better):
What I did find interesting, however, was a direct response from John C. Welch which he emailed to Manjoo and also posted publicly on his web site. Mr. Welch has been in IT “for around 20 years, from $bigCorp to higher ed, to small companies”, and from what I can tell he intends to speak for the industry. Let’s see how he rebuts accusations of infantilizing workers:
I'm sorry, where did I claim to speak for the entire IT industry. For that matter, where did I say that there aren't truly stupid/bad IT departments, or people? Hmm...no where. But, if you don't set me up as the self-annointed voice of IT, then the takedown isn't as much fun. I speak for myself Rob, and I'd think you were smart enough to figure that out without a disclaimer. (No, i'm not putting a fucking disclaimer in. If anyone is so stupid as to need one, they need to not read this site.)
Then comes the quote mining. Of course, Rob does a good job, first class job of quote-mining in fact. Of course, Rob doesn't include any context. I'm amazed he even linked back to the original post, normally, quote-miners don't do that. Bad form Rob, if you're going to quote-mine, do it right, or don't bother.
I'll skip the quote-mining, I already wrote the words, why reprint them? Now, onto his next statement:
Welch’s attitude towards his users, his bosses, and any critics of the IT industry is clear.
My attitude towards none of those is clear. My attitude towards Farhad Manjoo's idiot post, however, is crystal clear, and I'll not back down from that one bit.
What Rob doesn't seem to get is that it is perfectly, completely possible to dislike bullshit disguised as crusading for the little guy, and not hate everything about your work environment. I tend to not work for companies I dislike, it wears down the soul. See, here's the part Rob missed in his epic leap over Conclusion Canyon: I like my job. In fact, I took a pay cut to take my current gig, because my (then) soon-to-be boss and the company he represented was something I don't see often: A guy who can't do anything but shoot straight, and a fun as hell environment. That doesn't mean there aren't days I don't go home wishing I was a gargbageman instead. We all have bad days. But overall, I really like my current gig. I even, regularly, like my industry. THat does not however mean it's perfect. I think IT people, like any other group, are as capable of raging stupidity as any other, and there are a lot of well-reasoned criticisms of IT out there.
Manjoo's hack job was not one of them. It was childish and whining, and deserves as much vitriol as can be heaped upon it.
He does, of course, also include some unsubstantiated claims in his rant. It’s mostly just transparent hand-waving and misdirection, but I’ll make an attempt at a few of them:
Rob of course, is quite familiar with unsubstantiated claims, hand-waving and misdirection. So we'll accept him as authoritative on those subjects.
When employees need to beg the CEO for help getting around IT policy that makes it hard to work, the IT department has failed at its job. Disastrously.
If that is truly the only way to get things done, Rob is right. However, we don't know that. Unlike Rob however, I've a bit of direct experience in IT matters, and I can tell you that the percentage of time this is truly necessary is quite small. I will also agree, having dealt with it, and having quite a few friends who deal with it, that IT at the federal level is astoundingly slow-moving at times. However, that still doesn't meant that you aren't six kinds of an idiot to expect the Secretary of State to be familiar with the pros and cons of different browsers as they apply to the State Department.
An IT worker who considers the cost of disallowing any and all software to be zero needs a better understanding of “cost”.
I never said that, and this is a truly shameful example of Rob's bad attempts at quote mining. I never said this at all, because for one, it's patently not true. I'll guess that Rob is talking about this bit:
Bullshit. That is the precise word for this. Bullshit. Oh, the joys of firefox, until you have to deal with an internal site with old code that has sat there running fine, doing its job for years, but Firefox can’t use it. Oh sure, there’s a point that the site should be upgraded, but right now, it costs zero dollars to maintain, while upgrading it solely so that another browser can use it will cost...not zero dollars.
Of course, if Rob concedes that I'm talking about a very specific example, and not "the cost of refusing all software to be zero", then his point approaches zero as well. But, since Rob appears to need things explained to him simply: Like everyone else Rob, IT has a set amount of resources. Those have to be apportioned wisely, or shit can go to hell. That means that updating every internal web site so that you can use it in Firefox, while probably a good idea, may in fact not happen for a long time, if ever, when you have higher priorities, and the web site(s) in question are fairly low usage. Again, the existence of a browser does not require that it be fully supported. Even if people really, really like it. I say this as someone who regularly pushes for sites to be kept as up to date as possible with regard to standards, specifically so that we can worry less about what browser is being used. However, it's not a moral issue, it's a practical one. If you do things right the first time, you don't have to fuck with them as much.
Next:
We all know you don’t need intimate familiarity with every last detail of a network, “down to OS versions on routers and servers”, in order to install software. If you think that’s necessary, you don’t understand modern IT. And your security policy sucks.
Not only is Rob quote-mining here, but he's showing he sucks at it. Again, the original version:
Oh yes, how outlandish. Outlandish things like testing new versions of applications to make sure that the things you need to work right, work right. You’ll do that for us, right? Oh, did that Firefox plugin come up with a security hole? You’ll manage that update on your machine for us, right? You’ll read the staggering amount of security reports, mailing lists and newsfeeds that we have to just to keep on top of things. You’ll learn the details of the way the slate network is set up, down to OS versions on routers and servers, so you can tell what the implications of a security issue may or may not be. You’ll do all that for us, and never, ever, complain that it’s not your job to do that, that it’s IT’s job to do that, but never, ever, ever inconvenience you in any way, shape, or form in the process.
What Rob doesn't seem to get is that contrary to what he must think, a modern network is not a set of isolated loosely coupled nodes. It is, in many ways, reminiscent of a biological organism. (It's how I've thought of networks for over a decade, and if you haven't tried it you should. It can really help.) The idea that you can just change something and not have it affect other things is...I'll be charitable and say it's ignorant. Everything relates to each other, nothing happens in a vacuum. For example, a lot of people look at upgrading to Snow Leopard as a fairly pain-free exercise, and I'll say for many situations it is.
However, there are some changes made to the Java Implementation in Snow that if you aren't prepared, can catch you off guard. For one, Snow kind of sucks, in both Firefox 3.5.x and Safari, for talking to Cisco gear. Cisco uses Java for the ADSM stuff, but something about Snow's Java has issues with it. If you notice, you also see problems with the Java components of CS4 and Snow. Huh...how'd that happen. A ROUTER and a GRAPHICS SUITE having the same problems.
The meme Rob seems to be pushing is that if installing random software can fuck up your network, your network and its policies suck. As an IT person, Rob is a great programmer and CompSci Doctoral Student. I think he'd be rather amazed at how even minor bits of software can cause rather fascinating problems in ways you couldn't predict with a gun at your head. Like Aqua Connect Terminal Server freaking out serialnumberd in Mac OS X Server 10.5.8 on a single-homed Xserve, and completely fubaring the use of Kerberized AFP and SMB across the network. That was a fun one to figure out.
You get burned by freaky shit like that a few times, and you stop being sanguine about just installing stuff and hoping for the best.
We also have some idea of what it takes to keep computers and networks running. Most of us do that at home these days. Vague claims that “[it’s] not easy. No matter what your Googleh.D in computer science tells you”, are not good enough any more.
Rob, you'd think by now, you'd be too smart to fall for the "everything is the same" silliness, but okay. Evidently, keeping your home DSL router, a printer or two and a couple of WAPs running smoothly gives you an idea of what it's like to keep a global multi-platform network with over a hundred thousand users running.
Right.
Just like the fact that I can bang out some shell and AppleScript means I'm exactly as qualified for a Ph.D from Oxford as Rob's years of study and work have made him. After all, it's all computer science, right?
Seriously, that's just a laughable statement for anyone to make.
If management is making IT decisions, then they are running your IT department. Blaming bad policy on internal politics isn’t really a defense.
That's how it works in the real, (read: Non-academic) world Rob. Management, aka the people in charge of the company, set policy for the company. Even IT. When your corporate overlords say you cannot allow a personal computer on the company network without <criteria> being met, then while you may fight it, (and most IT departments do), if they refuse to relent, then that's how it is. If you can't live with that, quit. In all too-many cases, the people setting IT policy aren't doing it for the right reasons, and you get some truly stupid shit happening. Here's an example:
At one place I worked, we had some problems with people going on vacation, and the people who were supposed to take over for them not being able to get to work-related emails they needed to help out customers. IT gets asked if there's any way to help with this and we say "Sure, it's cake. We're on Exchange, sharing individual mail folders is trivial. When someone goes on vacation, they share the folders they need to share. When they come back, they stop sharing those folders. We can write up a nice howto, with screenshots if you like, and put them up on the internal site so folks can refer to it whenever they need." Oh no, we can't do that. Why, that would be horrible. Everytime we'd ask why, the answer never made a lick of sense, but since my title didn't start with "Executive VP", we came up with some convoluted-assed forwarding scheme that no one liked, and were forbidden to mention the quicker, easier way unless specifically asked about it.
Guess what Rob: Setting policy, even stupid policy is what management does. Following policy, even stupid policy, is what non-management does if they fail to convince management to change the policy. Welcome to reality.
We understand how email works. Forwarding a message to GMail doesn’t force you to delete the original. Really. Even if you throw acronyms like EAS and BES at us.
Again Rob, that's not what I said. What I said was:
There is not enough room here to detail how wrong you are about SOX. In fact, SOX doesn’t specifically proscribe much of anything. It’s a crappily worded law that gives almost no guidance, so the interpretations of the law come from auditors, and every company’s auditors do things differently. SOX auditors may only proscribe deleting emails for certain company officers, or they may proscribe it for all. They may require you to keep a copy of every email sent and received for the last n days, they may not. In some cases, auditors may very well proscribe forwarding email to Gmail et all. You never know until they tell you. So your interpretation of SOX, while convenient for your article, is um..incomplete. As well, the implication that somehow, you know more about the advantages and use of things like Gmail than every IT person everywhere? Can you even sit within arms reach of a computer, with your head all bloated like that? Oh, and your attempt to liken the use of things like EAS and BES to forwarding to Gmail? What you don’t know about such things would fill oceans. Oceans. But rather than learn, you instead run the New Media Douchebag playbook, and assume that only you, Farhad Manjoo, is able to really understand what’s going on.
Rob is really, REALLY bad at quote-mining.
This has nothing to do with deleting email, forwarded or not. It's that you now have forwarded company email on non-company servers that do not have to comply with the various rules and laws and policies about discoverablilty, retention, and all the rest of the bullshit that too many corporate IT people have to deal with that by and large, don't exist for academia. (FYI Rob, I worked for MIT, so I'm actually somewhat conversant with the far greater freedoms academia has in this area than corporate America, or even Corporate Britain does.) I don't agree with the paranoia about forwarding to Gmail et al, because about 70% of it is legal CYA, the solution for which is "don't do illegal or unethical shit, and you don't have to care". The other 30% tends to be legitimate security concerns, again, something that's not as common in academia as in other places.
Oh, yes, and Rob, it was Manjoo who was comparing the use of BlackBerries, iPhones, et al to forwarding email to Gmail, and that's simply not a valid comparison. EAS and BES are not the same as forwarding email from Account A to Account B, no matter how badly you try to spin it. (Rob's really bad at spinning, in case you hadn't noticed.)
If anybody wants to intentionally leak confidential data they can. Spending your time blocking IM and Twitter won’t change that.
OH MY GOD! REALLY! THANK GOD ROB SHEARER WAS HERE TO TELL ME THIS. BECAUSE NEVER IN MY LIFE HAVE I EVER FUTILELY ARGUED THAT TRYING TO USE TECHNOLOGICAL SOLUTIONS TO HUMAN/MANAGERIAL PROBLEMS IS DOOMED TO FAILURE AND RATHER FUCKING STUPID.
If there's anyone who doesn't realize that IT has progressed since the 80s, I'd say it's Rob.
We install applications on our personal machines all the time, yet we do not “spend hours a day dealing with application/OS/network interaction”.
"I can write shell scripts and use them with cron, gimme a Ph.D in CompSci from Oxford, I'm exactly as qualified as Rob."
Once again Rob, networks are not what you seem to think they are, and what you do at home does not perfectly replicate to every network on the planet, on any level. But, if you want to pretend they do, party on man. However, you may want to lay off the Guinness, I think you're starting to kill some of the important brain cells.
When big-company IT is no longer dominated by pathetic and incompetent despots then maybe the profession will regain a little bit of respect.
When academia isn't dominated by crusading quote-mining prats...oh fuck that, that's Rob's game. I know a lot of people in academia. By and large, they aren't like Rob. So I'll leave that shit to him.
Oh, and unlike Rob, I allow comments on my site. Way to man up there.
Douchebag.
| Comments ()