AppleScript Objective C Clippings

This isn’t a bug report, but more of a friendly suggestion, so take it for what you think it’s worth. After having moved all these ASObjC clippings into a sub-sub-sub-folder, I found them again (using Open Quickly searching for something else).

These are terrific, and I think could be a great introduction to ASObjC with a few minor tweaks.

For me, I looked at them when I first saw them, and even though I was curious, I figured they were too advanced for me and put them away. Had they been more “accessible” I think they would have been a lot more helpful.

Here’s my suggestions:

The ASObjC commands should be enclosed in handlers, and the clipping should have a working example of how to call the handler.

Each clipping then, as far as possible, should be able to run from a script, demonstrating how to use it. In other words, open a new script, hit run and the clipping executes, demonstrating the command. In some cases the user would be prompted to navigate to a file or folder, or may enter text in a dialog.

This would make it crystal clear exactly what parameters (class and values) the commands are expecting and what is returned (class and value).

There should be more clippings, grouped into subfolders in a logical manner based on the function.

Ed,

I looked at the ASObj-C clippings. I think the problem with trying to do what you said is if a person doesn’t know what the commands actually do, has no idea of ASObj-C syntax, no concept of the classes available or what those classes do then the text in in the ASObj-C clippings isn’t going to mean much.

Shane’s book gives a great introduction to all that. That is where I aimed my database, to people who were at least familiar with what was in Shane’s book. The kind of stuff you’re talking about is similar to what I did with the database and it wasn’t all that well received when I put it in the database. Some people really liked it but it was a small number.

I think I remember you saying you read Shane’s book. That made you familiar with the basic idea. The the database provided lots of examples to show people who read the book how to use the knowledge. Then the important part here is you worked with it using the database and asking for help when you had a problem. Now it’s starting to make sense to you.

As much as I hate to say it unless someone sees ASObj-C enabling them to do something they want or have to do it’s not worth the trouble. I was a bit different in that I didn’t have any particular need to fill. I had worked a long time with AppleScript and I wanted to try new things. So I spent a while learning ASObj-C before it did me any real good. Now I can see the benefit and what to learn more. Being able to have the extra power of ASObj-C means I can have a very powerful scripting language that can work directly with powerful applications. But a person has to want or need to take that step.

If you think about it would say this is correct? If not I would love to hear how you see it. It turns out it is pretty tricky to offer ASObj-C help. I would love to hear a way to make it more accessible and/or desirable to people. Right now the best way I see it is for them to go through Shane’s book and ask questions on line and then then use my database and continue to ask questions and with practice it gets a lot easier.

I could create examples using the code in clippings and explain it but this is not my code. If Shane or Mark asked me to do this I would. It’s the same kind of stuff I do in the database. I could even add the examples to the database that use stuff in the clippings, but again it is not my code. If I was wealthy enough to not need to work I would have a lot better database but I have to do it little by little.

Right now that database has 182 items in it covering methods, functions, constants, global variables, and classes as well as inheritance in the classes. I have another 25 things ready to add to the database. I have always expected to need at least a few thousand items to reach the minimum level I wanted for the database. Below that level the help is too spotty to fulfill the purposes I want it to. My goal is to replace the lousy text documentation with easier to read stuff and make the new information available in a fully accessible database. Since something is better then nothing I am making the database available before I reach that minimum number.

Bill

Shane and I will consider this, but please keep in mind that clippings are an editing aid rather than as a means of teaching ASObjC. They insert boilerplate code quickly. What you suggest would not be easily usable within an existing script (assuming I understand you correctly).

I’ll give you some examples of what I mean over the weekend. What I’m suggesting would be much easier to incorporate into a script than what’s there, and wouldn’t require knowledge of ASObjC.

The clippings wouldn’t teach ASObjC as much as introduce people to it and get them started using it without knowing all the nitty-gritty. Kind of the way some of us got started with appleScript.

OK, here’s a few samples of what I’m talking about. Of course they’d be formatted for clippings with placeholders. Each is based on one of the ASObjC clippings provided.

This format makes a lot of sense to me. It’s easy to implement and use in as script.

-- ASObjC Replace Considering Case
use framework "Foundation"

set textToSearch to "The quick Red Fox jumped over the brown fox's back"
set textToSearch to ReplaceConderingCase(textToSearch, "fox", "dog")

-- ASObjC handler
on ReplaceConderingCase(textToSearch, stringToFind, replacementString)
   -- classes, constants, and enums used
   set NSCaseInsensitiveSearch to a reference to 1
   set NSString to a reference to current application's NSString
   
   -- ASObjC commands
   set textToSearch to NSString's stringWithString:textToSearch
   set textToSearch to (textToSearch's stringByReplacingOccurrencesOfString:stringToFind withString:replacementString options:NSCaseInsensitiveSearch range:{0, textToSearch's |length|()}) as text
   
   return textToSearch
end ReplaceConderingCase
-- ASObjC Replace ignoring Case
use framework "Foundation"

set textToSearch to "The quick Red Fox jumped over the brown fox's back"
set textToSearch to ReplaceIgnoringCase(textToSearch, "fox", "dog")

-- ASObjC handler
on ReplaceIgnoringCase(textToSearch, stringToFind, replacementString)
   -- classes, constants, and enums used
   set NSCaseInsensitiveSearch to a reference to 1
   set NSString to a reference to current application's NSString
   
   -- ASObjC commands
   set aString to NSString's stringWithString:textToSearch
   set sourceString to (aString's stringByReplacingOccurrencesOfString:stringToFind withString:replacementString options:NSCaseInsensitiveSearch range:{0, aString's |length|()}) as text
   
   return aString
end ReplaceIgnoringCase
-- ASObjC - Contents of a folder 
use framework "Foundation"
use scripting additions

 
set fileORURL to choose folder with prompt "Select a folder"
set contentsList to FolderContents(fileORURL)
set entireContentsList to FolderEntireContents(fileORURL)

--ASObjc hander (accepts alias/returns list of URLs)
on FolderContents(fileORURL)
   set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
   set NSFileManager to a reference to current application's NSFileManager
   set {theURLs, theError} to NSFileManager's defaultManager()'s contentsOfDirectoryAtURL:fileORURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsHiddenFiles) |error|:(reference)
   if theURLs is equal to missing value then error (theError's localizedDescription() as text)
   set allPosixPaths to (theURLs's valueForKey:"path") as list
   return allPosixPaths
end FolderContents

--ASObjc hander (accepts alias/returns list of URLs)
on FolderEntireContents(fileORURL)
   set NSFileManager to a reference to current application's NSFileManager
   set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
   set NSDirectoryEnumerationSkipsPackageDescendants to a reference to 2
   set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:fileORURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsPackageDescendants + (get NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
   set allPosixPaths to (theURLs's valueForKey:"path") as list
end FolderEntireContents
-- ASObjC Make Unique List
use framework "Foundation"

set aList to {"The", "Quick", "Red", "Fox", "The", "Red", "Fox", "is", "Quick"}
set uniqueList to RemoveDuplicatesFromList(aList)

-- ASObjC handler
on RemoveDuplicatesFromList(aList)
   -- classes, constants, and enums used
   set NSOrderedSet to a reference to current application's NSOrderedSet
   
   -- ASObjC command
   set aList to (NSOrderedSet's orderedSetWithArray:aList)'s array() as list
   
   return aList
end RemoveDuplicatesFromList
-- ASObjC is option down 
use framework "Foundation"
use framework "AppKit"
set OptionKeyDown to IsOptionKeyDown()

--ASObjc hander (accepts alias/returns boolean)
on IsOptionKeyDown()
   -- classes, constants, and enums used
   set NSAlternateKeyMask to a reference to 524288
   set NSEvent to a reference to current application's NSEvent
   -- ASObjC command
   set theResult to (((NSEvent's modifierFlags()) div (get NSAlternateKeyMask)) mod 2) = 1
   return theResult
end IsOptionKeyDown

It seems to me that what you’re writing here is Ed's Lib . :slight_smile:

Once you go beyond in-line boilerplate code, libraries are the more logical place to put this sort of stuff.

I’d love to see more people using ASObjC – but I think it would be more useful generally to get them using libraries.

Ed,

This is the same exact what I did with examples in the database except in the database it goes to a different window and the example is seen as static text that can be loaded into SD and manipulated. You are trying to merge functional clippings and educational examples. They aren’t the same thing. If I go to a clipping I’m looking for it to do something for me in the quickest and easiest way possible. Not stop my work flow and teach me something.

I can tell you from experience not everyone is thrilled with having examples thrown at them. They want something to do something for them, now tell them how to do do it themselves. This is exactly the kind of problem I have ran into with the database. The vast majority want something to assist them to do “what they want to do.” It is better to do the teaching in a separate place.

I’ve been around to many scripters and programmers to think only asking them to go through a few more steps and learn something new is worth it. In a very large number of cases when I’ve been around people coding they get the job done first and later if you want to learn you do that later. It’s only when a coder is stuck and can’t go forward they will stop and figure out a new way. Breaking up coding with lessons can be very distracting.

I personally would never use anything that was trying to distract me with lessons while I am at work on a problem. But then again this is my opinion. Others may see it differently. Probably 10 people would have 10 opinions on something like that. In the end what matters is would people use it, ignore it, or be bothered by it and not use it.

Bill

The thing with libraries is that they are black boxes. You send a value in and you get a value back and you have no idea what’s going on.

[quote=“BillKopp, post:7, topic:495”]
This is the same exact what I did with examples in the database except in the database it goes to a different window and the example is seen as static text that can be loaded into SD and manipulated.[/quote]

No, it’s similar but not exactly the same. Your samples merge values and commands. Which means they require careful editing to repurpose and use. These examples, as rough as they are, put the values in variables and the commands in handlers making it both easier to know the values needed, and what the commands do and exactly what they return. Plus, these are easier to repurpose.

Yes, that is definitely the dichotomy.

Way back when, using well written clippings (in Scriptor Cal called them wraps) and other boilerplate appleScripts went a long way to helping me learn appleScripting and understand how things worked.

I have a ton of clippings in my SD clippings, and their purpose is exactly what you’re saying. A good number of them come from Mark, and those are all clear, well written textbook examples as to how whatever it is they’re doing should be done and what can be done.

So even to this day I’m still learning from reading well written appleScript clippings and other samples.

Not just that but in the built-clippings that come with SD there are already “examples thrown at you.” There’s an example open handler and a blank handler. There’s also examples for error trapping and dialog displays. (I wonder how many AppleScripter learned all the different things an error returned or a dialog could display by looking at SD’s clippings.)

The ASObjC clippings are much closer in design to the samples in the database with values intertwined with commands and difficult to repurpose (until you develop an expertise).

Ed,

The main thing I got from your post is the idea of repurposing examples and that clippings can insert things into a template with place holders to create a finished piece of code without the more difficult task of repurposing examples manually.

This raises an interesting point for the ASObj-C database. The database holds information useful to working with ASObj-C. I’ve left the fundamentals of teaching the basics of ASObj-C to Shane’s book.

But where does the concept of repurposing examples fit. It is something that fits between teaching the fundamentals of ASObj-C and where the database is. Neither goes into that subject a lot. Now that you bring this up it is really obvious. Although I completely missed it before. I need to broaden the specifications on the database. This is a functional design flaw in my original database specs. You are the first person who has brought this up to me. This is a very import but missing part of the database.

As far a using clippings for this purpose it still seems a bit strange to me but now I at least understand what you are talking about.

Bill

Ed,

Can you make a movie of what your are doing and point out the important parts. The database is full of ASObj-C information. In that respect the database might be more able to create what your looking for. I’ve been thinking about something helpful with repurposing ASObj-C examples. But for me it’s all automatic. I look at code, think about what I want to do different and then the new code just come to me in my mind.

Since you are using some kind of process with script debugger you must be doing something different from what I do. You only need to show one example where you walk me through what you do and what doing that action enables you to do, see, understand, … This step is between Shane’s book and the database. Many examples of repurposing scripts can be shown and that can help someone create a particular mental process to figure out example repurposing. But the database has actual computational power. It is a lot more then an information storing device. It can produce different outputs given some kind of starting point and some kind of specification of what to do with the starting point.

If that doesn’t work out then more examples would make it easier to spot repeating patterns of what makes a particular “ASObj-C something” work. Good examples can show what is necessary to get the code to work. Also I can add text descriptions to make this clearer.

When using something in ASObj-C one thing a user whats to know is what is always required, what is sometimes required and what kind of things are are not import for whatever “ASObj-C thing” that is being used.

I suspect when you first see an example in the database you are not sure which parts of the example are necessary for the “ASObj-C thing” being demonstrated. In part my example might make this problem worse. When I do an example I try to show it in the context of accomplishing something. This makes the thing being demoed easier to understand but at the same time it could leave the user wondering what parts are needed for the demo, but not needed for the “ASObj-C thing.”

Bill

Not sure what you want a movie of. It takes me about 10 minutes to turn simple clipping or sample into a handler, and then make that handler a clipping.

Ed,

I’m trying to figure out if the process of converting the stuff teaches you something, or if having the converted stuff allows you to do something that teaches you stuff. I’m trying to figure what kind of clipping you wanted set up. What is it about the clipping that makes it a learning tool. What was it about the existing existing clippings that failing to teach you what newer clippings would teach. Are examples better or worse then this new kind of clippings. Could the use of more comments in the examples in the database make make the examples as good as the new way. These are the kinds of things I’m trying to figure out.

I would like to address what you were asking for but I am not sure what you asked for.

Bill

OK, here’s a 10 minute movie of me learning about one particular clipping.

It’s the Entire Contents clipping, and at the end of the video it’s not working cause I didn’t copy a use statement.

I point out a couple things about the clipping I don’t get.

Also, as for the database, I spent about 5 minutes seeing if I could find simple commands or concepts without already knowing where they were.

The biggest favor you could do for your users at this point is make searching simple and effective.

Ed, I think you forgot to post the link to the video.

Ed,

I watched your video. Here are my initial thoughts after the video.

I noticed some difficulties right away watching what you were doing. The first difficulty I saw was you have figure out is going on and there are no comments. There are unfamiliar command in the clippings, it would be harder to avoid accidentally putting a line before something when the line needs to go after it, the clippings are out of context in that they are not shown inside a larger script that actually accomplishes a task, and I’m guessing there is a lot of trial and error in the process.

The overall process seems to be geared to getting individual ASObj-C commands into a handler and accessed that way. I’m guessing you come to understand the command by using it from inside a handler.

This process looks tough for someone new to ASObj-C. If someone just turned the script into a regular ASObj-C script, put it into a handler and added comments I would think the process would not be so bad for you. I could actually do that for you.

Shane does the same thing with handlers in his book. He creates handlers to to demonstrate new commands. That is probably the better way for people new to ASObj-C. I think I should just make all the beginning examples use handlers. Once someone becomes more familiar with ASObj-C that would be more work than is necessary but it would probably be better for beginners.

Also the beginning examples should list which lines need to go before or after other lines. All commands used should be briefly summarized and their corresponding framework should be easy to determine. For references to lines that not contain the class name in the line the class name should probably be listed in a comment.

Using clippings as a source for a script gives you something very similar to what is called a code snippet. These are geared for someone who has a decent understanding of the overall things involved in a script and just wants to see a detailed example of implementing a particular command or a very small part of the process. You would benefit more from seeing examples set in the context of accomplishing something. Starting with a clipping gives you a bit of tunnel vision. Once you became familiar enough with ASObj-C to convert such things easily you probably would not to do such things any more.

I’m not sure you learned a lot from doing the actual conversion as much as the debugging that goes on afterwards. Also I got the feeling what made clipping valuable to you was it was something only 1 step away from working source code.

I think examples could be better for you then the conversion process if I changed the way I did examples for beginners.

So what are your thought on my thoughts?

Bill

@estockly, sorry but after having waded my way through this thread and your video, I have to disagree.

As I understand “Clippings”, they are intended to be relatively short blocks of code that one inserts into the script you are working on.

In fact, this is what the SD Help says:

Clippings are bits of boilerplate text that you can insert into your code.

Look at the non-ASObjC clippings, like “change list to string”:

This is too could be put into a handler (I already have such a handler), or you could just use as intended, inline in your script.

And just like the ASObjC clipping you tried, it gets an error if you try to run it without any additional code. I believe this is expected, and normal.

So, I don’t want a bloated clipping that tries to do more than just give me the code I need. If I want to take that and make a handler out of it, then that is easy enough to do.

One excepting to my “non-bloating” comment, is with ASObjC clippings.

I think there are so many of us who barely, or not at all, understand ASObjC and/or how to use it, that providing some brief comments in the ASObjC clippings would be very useful. And maybe even a link to the relevant documentation where we can get more details.

Just my 2¢. :smile:

Appreciate your comments, Jim.

I’m not suggesting that all the clippings be reworked and handlerized. Just the ASObjC clippings.

The problem is that you’re wanting to turn a shortcut into a learning tool. When I choose a snippet, I generally want some piece of code inserted, not a lesson on how to use it. If lessons are needed – and I agree they are – they belong somewhere else. Something like a dedicated thread (or threads) here, perhaps.