Passing as reference as Argument to ObjC object

I’m trying to speed up my ASOC app to work separately on files and folders. The handler fileExistsAtPath:isDirectory: has to return a value from the second argument to the calling method.

--   set NSFileManager to class "NSFileManager" of current application
--   set theFileManager to NSFileManager's defaultManager()
on isFileOrFolder(thePath)
    local isDir, isDirRef, theResult
    set isDir to true
    set theResult to theFileManager's fileExistsAtPath_isDirectory_(thePath as text, a reference to isDir)
    log "theStr: " & theStr as text
    log "isDir: " & isDir as text
    log "theResult: " & theResult as text
end isFileOrFolder

using isDir and reference to isDir both give the same error:

How do I get the value of the second parameter after the end of isFileOrFolder?

I believe you’re out of luck – at least, everything I’ve tried fails. There doesn’t seem to be any way to pass pointers to C types or pointers to object pointers. I suggest you log it as a bug – the more who do, the better.

How do I report a bug?

Have you tried it with a property as the boolean value isDir ?
I guess you can’t reference a simple local variable

I get the same error message as before. I guess I’m left with finding out how to report a bug. It definitely seems to be one.


I’m wondering if this works at all.
An AppleScript reference is actually the equivalent to the asterisk (*) in ObjC.
The fileExistsAtPath:isDirectory: method expects the address pointer (&) which is not the same.

Is there any documentation about this case?
It’s not a bug until it’s supposed to work but doesn’t :wink:

There’s not much documentation period. The template for a doc-based app uses syntax that tries to work with NSError **, but it doesn’t seem to work. The template for an NSDocument subclass says, in part: “AppleScript/Objective-C does not support (NSError **) parameters yet.”

In the absence of documentation, I think it makes sense to log it as one.

You could try this:
Make yourself an instance of the NSError object, and initialize it with “junk” values. Put the object into the method as needed. Hopefully the method will fill in the error object’s pertinent dictionary if it fires. It seems to work. Can anyone verify this better?

set andError to current application's NSError's alloc()'s initWithDomain_code_userInfo_("me", 909, missing value)
	set createdFolder to false
	set pathExists to (NSFileMan's fileExistsAtPath_isDirectory_(posixPath, missing value))
	if (not pathExists) then
		set createdFolder to NSFileMan's createDirectoryAtPath_withIntermediateDirectories_attributes_error_(posixPath, false, missing value, andError)
	end if
	if (not createdFolder) then
		log andError
		log "simple error"
	end if

here’s what I get from ASOC Explorer 2:
11:58:54.149 [128] set pathExists to (NSFileMan’s fileExistsAtPath_isDirectory_(posixPath, missing value))
→ true
11:58:54.150 Error Domain=me Code=909 “The operation couldn’t be completed. (me error 909.)”
11:58:54.151 simple error
11:58:54.152 An error has occurred. (-2700)

I don’t know if this would be a generic error, or this actually returns the actual error that createDirAtPath gives when it fails. I haven’t tried a corresponding Cocoa app to test it yet.
Using this on 2012-03-08, on OSX 10.6.8, ASOCEXplorer 2.2.1

if I make conditions where the code will succeed in creating the folder, then I get this in the log:
13:12:40.633 *** -[NSFileManager createDirectoryAtPath:withIntermediateDirectories:attributes:error:]: value passed to argument of type ^@ must be either missing value' or reference’; assuming `missing value’.
13:12:40.633 [132] set createdFolder to NSFileMan’s createDirectoryAtPath_withIntermediateDirectories_attributes_error_(posixPath, true, missing value, andError)

You can just use: set {theBool,theResult} to theFileManager’s fileExistsAtPath_isDirectory_(thePath,reference)
theBool is the normal return value for this method and theResult will contain’s the BOOL that is returned by reference.


Right. The only place this doesn’t seem to wrk is with methods that don’t return a result. Some of the get[…] methods are examples.

I have found a way, for at least some cases, to get results from methods that don’t return a result except through C pointer arguments.

An example is the NSColor method getRed:&redVal green:&greenVal blue:&blueVal alpha:&alphaVal that places the r, g, b, and alpha values of an NSColor in C pointer arguments. Here is a Cocoa implementation:

- (void)getRGBValues
	CGFloat redVal, greenVal, blueVal, alphaVal;

	NSColor *sampleColor = [NSColor purpleColor];
	[sampleColor getRed:&redVal green:&greenVal blue:&blueVal alpha:&alphaVal];

	NSLog(@"r=%f g=%f b=%f a=%f", redVal, greenVal, blueVal, alphaVal);
	NSLog(@"%@", sampleColor);

The first NSLog returns: r=0.500000 g=0.000000 b=0.500000 a=1.000000
The second NSLog returns: NSCalibratedRGBColorSpace 0.5 0 0.5 1

Notice that the second NSLog includes the desired results without resorting to the getRed:&redVal green:&greenVal blue:&blueVal alpha:&alphaVal method call. One can take advantage of this “leakage” by parsing the NSLog output. The following handler is an ASObjC solution. It is assumed to be in an ASObjC applicaiton named “ColorGetter” (the actual application name should be used instead of this, so that grep can home in on the appropriate entry in the system log):

on getRGBValues()
	set sampleColor to current application's NSColor's purpleColor
	log sampleColor
	tell paragraphs of (do shell script "" & ¬
		"cat /var/log/system.log | " & ¬
		"grep \"ColorGetter\" | " & ¬
		"tail -1 | " & ¬
		"sed -E 's/^.+ ([0-9.]+) +([0-9.]+) +([0-9.]+) +([0-9.]+) *$/\\1\\" & linefeed & "\\2\\" & linefeed & "\\3\\" & linefeed & "\\4/'") to ¬
		set {redVal, greenVal, blueVal, alphaVal} to {(item 1) as real, (item 2) as real, (item 3) as real, (item 4) as real}
	return "r=" & redVal & " g=" & greenVal & " b=" & blueVal & " a=" & alphaVal
end getRGBValues

Running getRGBValues() returns: "r=0.5 g=0.0 b=0.5 a=1.0
which is the desired result.

This is admittedly a hack for an otherwise desperate situation.

Lots of points for effort, but I’m not sure why you wouldn’t use redComponent(), greenComponent(), &c, instead.

Thank you for pointing out the …component() methods. They are certainly the optimal way to get the RGB components of an NSColor. Still, the primary purpose of my example was to show a potential solution to getting values returned in C pointer arguments where no alternative exists.