Re: Tell Blocks Considered Harmful (was Re: open for access)
Re: Tell Blocks Considered Harmful (was Re: open for access)
- Subject: Re: Tell Blocks Considered Harmful (was Re: open for access)
- From: Ed Stockly <email@hidden>
- Date: Tue, 16 Dec 2008 10:26:41 -0800
Yes. It's unnecessary and undesirable to put many of those scripting
addition commands inside that tell block.
Placing all those lines inside the tell block confuses things and
makes it more difficult for someone reading the script to know
whether the script is intended to depend upon sending those commands
to Finder.
So what? What does it matter if someone looks at the script and
doesn't know if the finder is the process that handles the OSAX or
something else? The command works, the process runs. No sweat, no
problem.
It makes for a smooth, easy to read, easy to understand script. As the
scripter learns more about the technology they grow beyond that.
I can tell you, based on my experience, that that was true for me. I
learned to write OSAX commands inside applications (not the Finder
back then, it wasn't scriptable) and then learned that they could be
run outside tells and from that moment I had no confusion at all. I
felt I had more options.
Instead, I would probably write:
tell application "Finder"
set myFileName to name of my (choose file)
set myFiles to every file of my (choose folder)
end tell
set the name of myFile to the text returned of (display dialog
default answer "File Name")
set the name of myFile to date string of (current date)
tell application "Finder" to set myFile to every file of my (choose
folder) whose modification date < my (current date)
set myCase to ASCII character of character 2 of the name of myFile
Now we can see that only three lines actually need to involve
Finder, and none of the scripting addition commands need to be sent
to Finder. Note that you can use "my ..." and "... of me" to send
commands to the script (and ultimately to the application running
the script) without breaking them out into separate lines.
Yes, but that's far more scripting structure, it's more wordy, it's
not as intuitive. Requiring that kind syntax makes it more difficult
to get started with appleScript.
Note that whether the dialog is displayed in front of the active
application is a separate issue from whether the dialog is displayed
within the application, preventing user interaction with the active
application.
It is important for me to find out which aspect is important.
OK, two issues, and both are important. Issue one, which application
displays dialogs and user interface items. I want to control that for
several reasons.
As the script runs I want to control what application is frontmost
in order to give the user a consistent look and feel. If I activate
app A, I don't want the UI focus to change arbitrarily to whatever
process is running the script just to display UI elements. I want to
choose which app displays UI elements.
Issue two, do I want my modal dialogs to effectively lock out all
other user interaction with an application?
That's how it works now. If Quark is displaying a dialog, I can't do
anything else with quark. I have no problem with it.
I've always thought it would be nice to display a non-modal dialog
that would give me the option to display a dialog within an
application that allows interaction, but I'd be very careful about
using it.
Something like
tell application "Photoshop"
display dialog "Crop the photo as desired, then click OK"
end
But short of that, I would want to limit user interference with an app
displaying a dialog...
And yes, it may be critical that the user doesn't interfere when a
script is running.
But interfere with what, exactly? Is it important for a script
running in process A to prevent users from interacting with process
B by displaying a modal dialog in process B? Note that the script
will pause and process A will typically not allow user interaction
while the script is waiting for process B to respond to the dialog
command.
Changing the front most document in an application could screw
everything up with a single click.
Which actually brings to mind another reason it's better to include
osax calls in a tell.
Tell application "Quark"
tell document 1
set myText to contents of text box 1
display dialog xxxx
....
Once I've started the document tell block, my script is addressing
that document, even if another document becomes document 1, for as
long as I stay inside that tell.
But if I have to end that tell to call call an osax then go back to a
new tell document 1, a different document may be frontmost and I can't
use the simple "tell document 1" but will have to do more elaborate
ways to address the document.
Tell application "Quark"
tell document 1
set myText to contents of text box 1
end tell
end tell
display dialog xxxx
Tell application "Quark"
tell document 1 -- may not be addressing the same document as previous
tell
set myText to contents of text box 1
end tell
end tell
Here's how I'd assume it would be handled. AppleScripts are always
launched from within some application. Either the finder, or an
applications scripts menu or a system process.
Define "launch". When you open an application, that is called
"launching". If you open a script applet, that is "launching". But
if you run a script within an application, that's "running a
script". The key difference is that the script is running inside an
existing process, not creating a new process.
OK, I'm a scripter, not a programmer, so I wasn't clear on the
distinction between running and launching. This is what I should have
said:
AppleScripts are always run from within some application or process.
Either the Finder, or an application's scripts menu or a system process.
Even if they're sending commands to a process with additional
privileges, they should not have privileges beyond their inherited
privileges without some kind of authorization.
Exactly. Today they do. Scripting commands operate with the
privileges of whatever process is handling the command.
Right, and I guess if that's a problem you should fix it, but don't
throw the baby out with the bath water.
If launched from the finder they should not have permission beyond
what the user has in the finder, and the same should be true for
any application or process.
You cannot run a script within Finder. You can launch/open a script
applet from Finder. But then the applet is running in its own
process and is not subject to Finder's privileges. Every process has
its own rights and privileges. This is the problem with sending
certain commands from one process to another.
What about a script run from the scripts menu when the finder is
frontmost app?
If you sent one of these other processes a ‘do shell script’
command it would execute that command using the privileges of that
user instead of yours.
I can see how shell scripting can open a new dimension of
challenges, but the shell scripting mechanism also has ways of
passing a user or administrator password that can allow additional
privileges.
You cannot normally invoke ‘do shell script’ with administrator
privileges without actually supplying the ‘with administrator
privileges’ parameter. But if you send ‘do shell script’ to a
process that has administrator privileges, the ‘do shell script’
command and the shell commands it invokes all run with administrator
privileges. This is (approximately) the problem that Security Update
2008-005 addressed.
I would really hate to see the entire language munged just to allow
for an additional vulnerability introduced by 'do shell script'
To "allow for" a vulnerability? Just the opposite. The goal is to
eliminate vulnerabilities by preventing scripts from sending unsafe
commands to other processes. They should instead send the commands
to the process that is running the script.
I should have said: I would really hate to see the entire language
munged just to eliminate an additional vulnerability introduced by 'do
shell script'
Has [Security Update 2008-005] broken many scripts in the wild?
Some. And in every case so far, the breakage has been due to scripts
placing scripting addition commands inside tell blocks, thereby
sending them to other processes when it was completely unnecessary
to do so.
And let us keep writing osax commands in tells.
And that is what I was talking about. How to do that? The simplest
way is to always handle scripting addition commands in the process
running the script instead of sending them to the tell target. But
this has compatibility risks. Some commands behave differently
depending on the process they are handled in, and some scripts may
rely upon this (intentionally or incidentally). And there are
programs that send scripting addition Apple Events without using
AppleScript.
Yea, well tough luck for them, all I care about is appleScripters. The
programmers should have known better. If you're going to give people
headaches give them to the programmers not the scripters.
As for users not knowing if it's the finder that displays a file
dialog or an osax, that's part of the zen of appleScript.
Huh? ‘display alert’ displays a modal dialog. The application that
displays the modal dialog prevents user interaction with that
application until the user dismisses the dialog. Users can easily
see which application is displaying the dialog. The question is, do
you as a script author need to be able to block user interaction
with arbitrary applications that you target, even though they are
not the ones running the script?
But it's not arbitrary. The process that the script runs under may be
arbitrary but the scripter decides which app displays the dialog after
careful consideration.
We can write scripts that work and not know all the details or even
the basics about how things work, and our scripts work. As we learn
more about scripting those details reveal themselves.
Yes. And languages should be designed to make it easier to write
correct programs and harder to write incorrect programs, especially
programs that are subtly incorrect in a way that's not obvious to
users, especially the less experienced ones. I'd rather the language
minimized how often this happened by requiring the user to be more
explicit about which events are intended to be sent to other
applications.
Which means adding steps to making very simple commands work, which
adds barriers to entry. AppleScript is hard enough for programmers and
non-programmers to learn, don't make it worse. Especially don't make
it worse for some nebulous benefit that most appleScripters won't even
be aware of or benefit from.
Tell blocks and scripting additions as they exist today enable and
even partly encourage sloppy scripts with lots of code unnecessarily
within tell blocks, and lots of events unnecessarily being sent to
other processes.
Yes, but that's not as bad as it sounds. That's the price paid for the
ease of learning to AppleScript. And with the speed of processors
these days, the overhead for the finder or another app handling an
OSAX compared to whatever process happened to launch it is minimal.
Sloppy scripts and unnecessary code is a very low price to pay for the
benefits of having such an easy to learn and easy to use technology
with the grasp of your users.
I do appreciate the effort you're making to get a sense from scripters
how to proceed. In other realms these kinds of changes would be
introduced as a fail accompli and it wouldn't be long before the
technology would "evolve" into something useless.
ES
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users
This email sent to email@hidden