Showing posts with label path. Show all posts
Showing posts with label path. Show all posts

Friday, 15 June 2012

Undocumented feature - interrupt - part five


Continuing from part four where we looked at "4", "5" and "6"...


7 - Parent directory


This sets $result to be the parent directory of the file path that you specify, like this...


  interrupt(7,"C:\temp\test\")
  parent = $result



In this case $result would be set to "C:\temp\".  You could do this with string manipulation, but you need to be careful that you check to see if the last character is a delimiter or not...

  filepath = "C:\temp\test\"
  if ( $scan(filepath,"/") < 1 ) ;calculate delimiter
    del = "\"
  else
    del = "/"
  endif
  pos = $length(filepath)
  if ( filepath[pos] = del ) ;remove last character if delimiter
    filepath = filepath[1:pos-1] 
  endif
  pos = $rscan(filepath,del) ;find last delimiter
  filepath = filepath[1,pos] ;truncate string

As you can see, this isn't very concise either, and uses $rscan as well as $scan, so it's not likely to perform very well.  As with "6", I'll test with and without the code which calculates the delimiter, over 2,000,000 iterations...

  • interrupt = 00:05.16, 00:05.20, 00:05.09 (just over 5 seconds)
  • alternative = 00:17.74, 00:17.52, 00:17.67 (over 17 seconds)
  • without $scan = 00:15.62, 00:15.39, 00:15.41 (over 15 seconds)

Looking at these times, I'm struggling to argue for using the alternative!  I'm thinking I must be doing something wrong, so I'm going to try and refactor my alternative, without $rscan.  

I've just tried using $replace to convert the file path into a list, remove the last item (or two) and then convert it back again - this took slightly longer!  I'm going to have to give up with this for now, but I hope to tackle this again.


8 - Unknown


I haven't found any indication of what functionality this might be, but it does behave differently to "1" and "4", which are also unknown.  In this case it always returns a $status of 0 and $result is set to the string that you pass in.  I've tried all sorts of weird and wonderful things without getting anywhere, I'm giving up on this one for now too.



9 - Unknown


I haven't found any indication of what functionality this might be either.  This also behaves differently, as it always returns a $status of 0 but $result remains unaffected. 


Summary: Numeric code "7" could be very useful for finding the parent directory quickly, but "8" and "9" remain unknown.



Wednesday, 13 June 2012

Undocumented feature - interrupt - part four


Continuing from part three where we looked at "2" and "3"...


4 - Unknown


I haven't found any indication of what functionality this might be, but it does behave differently to "1", which was also unknown.  In this case it always returns a $status of 0 and $result is a blank string.  I tried folders, subfolders, filenames and a blank string, with no difference in behaviour.  I'm giving up, for now.



5 - Working directory


As discussed in part one, using numeric code "5" returns the working directory...

  interrupt(5,"")
  working = $result

The alternative is to use $ldir...

  working = $ldir()

The alternative is more maintainable, safer and also performs better.


6 - Concatenate file path

This takes the file path which is currently in $result and then concatenates the path you pass in, automatically adding the folder delimiters where necessary.  Here's some example code...


  filepath = "C:\temp"
  $result filepath
  interrupt(6,"test")
  filepath = $result



This will then populate $result with "C:\temp\test\".  As you can see, I had excluded the delimiter from the end of both the original $result value and the value I passed it, but the interrupt command fixed that.  Again, this is another string manipulation example, I came up with something like this...



  filepath = "C:\temp" 
  if ( $scan(filepath,"/") < 1 ) ;calculate delimiter
    del = "\"
  else
    del = "/"
  endif
  pos = $length(filepath)
  if ( filepath[pos] != del ) ;check filepath ends with delimiter
    filepath = "%%filepath%%del%%%"
  endif
  filepath = "%%filepath%%%test%%del%%%" ;concatenate filepath



As you can see, this isn't very concise, primarily because I'm accounting for Windows and Unix environments again, meaning that I have to first calculate the "del" local variable.  You could of course use $concat instead of using substitution, like I have.


I tested these two methods over 2,000,000 iterations with the following results...

  • interrupt = 00:06.67, 00:06.75, 00:06.72 (almost 7 seconds)
  • alternative = 00:12.02, 00:12.00, 00:12.04 (about 12 seconds)
  • without $scan = 00:09.04, 00:09.78, 00:09.74 (almost 10 seconds)

I added a third option which was the alternative but with a hardcoded delimiter instead of calculating it, so the performance can be improved by having a global register that holds this.  Still, in this case the interrupt command is better for performance and is less lines of code.  

Summary: Numeric code "4" remains unknown for now, "5" has been replaced by a better alternative and "6" seems to still be useful, although I think I'd still opt for string manipulation which I know that I can control over an undocumented feature.


Tuesday, 12 June 2012

Undocumented feature - interrupt - part three

Continuing from part two where we looked at "0" and "1"...



2 - Extract filename


This seems to extract the filename part of a full path, removing the directory structure.  Here's some example code for you...



interrupt(2,"C:\temp\test.txt")
filename = $result

In this case "filename" will be populated with "text.txt".  This does seem to be a simple case of string manipulation, but if you support both Windows and Unix filesystems (which the company I work for do, and I expect a lot of people will if they are doing any web development) then maybe it's not so simple...



filename = "C:\temp\test.txt"
pos = $rscan(filename,"\";for Windows
if ( pos < 1 )
  pos = $rscan(filename,"/";for Unix
endif
filename = filename[pos+1]



So this requires a numeric local variable and a few extra lines of code to achieve.  I tested for 2,000,000 iterations...



  • interrupt = 00:09.35, 00:09.30, 00:09.33 (over 9 seconds)
  • $rscan (Windows first) = 00:14.72, 00:14.75, 00:14.66 (under 15 seconds)
  • $rscan (Unix first) = 00:16.38, 00:16.41, 00:16.31 (over 16 seconds)

Unfortunately $rscan is a pretty slow function, but as they could be multiple folder delimiters in the string, I don't see how it can be avoided.  You have to choose in your code whether to put Windows or Unix first, unless you have a global setting somewhere which tells you which the application is running on, in which case you could limit this to a single $rscan.  

Whilst interrupt does perform better in this case, I would say that it is more than likely negligible, given the number of iterations.  Therefore, I'd choose to use the alternative, as I know that I can rely on it working in future.

3 - Extract file path


This seems to extract the file path part of a full path, removing the filename.  Here's an example...



interrupt(3,"C:\temp\test.txt")
filepath = $result

In this case "filepath" will be populated with "C:\temp\".  The alternative to this is therefore going to consist of a similar bit of string manipulation...

filepath = "C:\temp\test.txt"
pos = $rscan(filepath,"\";for Windows
if ( pos < 1 )
  pos = $rscan(filepath,"/";for Unix
endif
filepath = filepath[1:pos]


So there's no need to measure the performance of this, the different will be very similar.

Summary: Numeric codes "2" and "3" do seem to be useful and perform better than the alternatives.  However, the performance difference is probably not enough to consider using the interrupt command, as it will be less maintainable and risky moving forwards.  I'll continue in the next part.