[quote=434463:@Tim Streater]
Is there a reason for this? I may say that as far as I’m concerned, the behaviour of GetFolderItem is correct in this situation.[/quote]
Yes - and its not a bug
Constructors dont “return” anything
A constructor is just a “special” initializer - but its still just a method (you could in fact call it manually if you wanted)
Basically when you use “NEW X” the construction the sequence is
set aside memory for the object with all values initialize to defaults for the type
this means the object exists and CANNOT be nil
run the constructor method to initialize the values
and now the setting of those initial values fails - but the object still exists so its not nil
The file in question may actually be anywhere in the file system, I just chose Desktop as an example.
In essence the problem surfaced because the particular filename happened to contain (perfectly legally under macOS) the directory separator of the underlying OS. If this is viewed as an error, I don’t see why the Constructor can’t (in this instance) free the memory and initialise fh to Nil.
Hmm. The file(s) get selected in the first instance by the user by drag/dropping them, and ISTM I shall have to forbid such files at that stage, since obviously I can’t actually open them (can’t do much if GetFolderItem returns Nil or new Folderitem gives an exception). The DragItem gives me a FolderItem which contains the filename and path, thus:
Constructors are not “allocators” - they dont allocate memory like they do in something like C++
When you use “NEW whatever” the memory is ALWAYS set aside - period
So the object ALWAYS exists when you use “NEW X” and there is no way for the constructor to nil that if something goes wrong
Doing so would be a fundamental change to the entire runtime and VERY unlikey to every happen
FWIW this is not unique to Xojo.
Java constructors behave nearly identically - except that Java prevents you from calling the constructor any other time
Ha ha. I wondered when someone would ask that. It’s a good question.
The user chooses the files, and I make a note of their names and paths in an SQLite database.
At some later point, which could range from minutes to years (but is typically a few minutes), the user wants the files processed. In between times, they could have shut down the app, re-booted, deleted half the files they selected, renamed the other half, changed their mind about actually which files they want processed, any number of things. The best I can do is keep track of their whims and then, when they later press to Go button, manfully knuckle forehead and do it.
Function GetFolderItem(path as string, pathType as integer = Folderitem.PathTypeAbsolute) as Folderitem
try
dim f as new Folderitem(path, pathType)
return f
catch usfx as UnsupportedFormatException
return nil
end try
end Function
but there’s no way to rewrite “new folderitem” such that it could return nil - since it doesnt “return” anything
It’s not quite a good idea to combine f.Name and f.Parent.NativePath
See what @Thomas Tempelmann has written in this post:
[quote]in Xojo’s FolderItem and in the Finder you can name a file “a/a” but not “a:a”. The “:” then gets swapped with “/” if you’re using POSIX or Shell paths.
Meaning, if the Finder shows “a/a”, the file’s name in Terminal will be “a:a”.[/quote]
Or in an example:
f. Name, f.DisplayName: 2018/19 mypic.pngit’s what the user sees, and may contain a /
f.NativePath: /Users/username/Desktop/2018:19 mypic.pnga user-entered / will be a :
f.ShellPath: /Users/username/Desktop/2018\\:19\\ mypic.pnga user-entered / will be an escaped :
Store the “Name” for Display purpose, but store the full “NativePath” or “ShellPath” of the file (and not just of it’s .Parent folder) to access it later.
That works just as expected:
[code]Dim f1 As FolderItem = GetFolderItem(“/Users/username/Desktop/2018:19 mypic.png”, FolderItem.PathTypeNative)
Dim f2 As FolderItem = GetFolderItem(“/Users/username/Desktop/2018\:19\ mypic.png”, FolderItem.PathTypeShell)
Dim f3 As New FolderItem(“/Users/username/Desktop/2018:19 mypic.png”, FolderItem.PathTypeNative)
Dim f4 As New FolderItem(“/Users/username/Desktop/2018\:19\ mypic.png”, FolderItem.PathTypeShell)[/code]
fDirectory = GetFolderItem (fpath, FolderItem.PathTypeNative)
if fDirectory <> nil and fDirectory.Exists and fDirectory.Directory then
fItem = fDirectory.Child(fname)
end if
fDirectory = new FolderItem (fpath, FolderItem.PathTypeNative)
if fDirectory <> nil and fDirectory.Exists and fDirectory.Directory then
fItem = fDirectory.Child(fname)
end if
[/code]
Again: Just don’t mix/combine “NativePath” and “Name”.
… and stop using illegal characters in your file names for your own sanity. Remember, just because you can, doesn’t mean that you should. Stay away from:
[ ] { } \\ | / ? < > : ; ! @ # $ % ^ & * ( and )
All of those have special meaning on Unix/Linux/Mac systems (and some on Windows). You’ll thank yourself later.
[quote=434500:@Tim Jones]… and stop using illegal characters in your file names for your own sanity. Remember, just because you can, doesn’t mean that you should. Stay away from:
[ ] { } \\ | / ? < > : ; ! @ # $ % ^ & * ( and )
All of those have special meaning on Unix/Linux/Mac systems (and some on Windows). You’ll thank yourself later.[/quote]
I agree. But they’re not my files; they are other peoples’ files. I have no control over how they choose to name their files.
fDirectory = GetFolderItem (fpath, FolderItem.PathTypeNative)
if fDirectory <> nil and fDirectory.Exists and fDirectory.Directory then
fItem = fDirectory.Child(fname)
end if
[/code]
Again: Just don’t mix/combine “NativePath” and “Name”.[/quote]
Thanks - this does the trick nicely. I noticed that this doesn’t work if one is using xojo.io.FolderItem. What happens then is that the portion of the name that looks like path info is appended to the folderitems’s path info, and the filename is reduced to the residue (which in the above case would be “19 mypic.jpg”. I’ll ask separately about that and open a case if it’s a bug.
You can at least lessen your responsibility by documenting these characters. There is no limit to the “creative” manner in which a user will abuse their power on a system. The fact that Apple “allows” those characters is the big dumb-■■■ move in the environment.
I’ll hold to my BOFH statement from 1990 - Computer use should require a license - like driving.
Actually there is another set of files the user can name and there I essentially do prevent the / char. But perhaps I should put something about it in the User Guide - not that people ever read those.