Friday, January 6, 2012

011 - Learning libraries

I got asked to show how I go about figuring out how libraries work, and to explain exactly how I make use of Factor resources (the documentation, the walker, the inspector, etc) to achieve that goal.

The example I was asked to use was to be able to use the FTP library to retrieve a file from a password-protected FTP server. Here we go.

N.B.: I use "to drill down" to mean something a bit hard to explain with words - it's the action of browsing the source code of a word in the Browser and progressively click each specified word to browse its source code in turn; this is interactive code spelunking.


  1. To brush up on FTP commands, I googled for: ftp unix tutorial password download. Turns out it's very simple.
  2. Switched right to the Factor docs, searched for FTP, clicked on ftp.client.
  3. Looked at the list of commands trying to try and make sense of it. A good way to make sense of libraries is to find the basic building blocks - the least abstract functions that provide the support for the higher level ones.
  4. Since the command to download a file is GET, I clicked on ftp-get and drilled down to both with-ftp-client and ftp-cwd.
  5. I saw that ftp-cwd calls ftp-command. This looks like the basic building block I was looking for. Its source confirms that this is very concrete (i.e. it does something I can promptly understand - namely, send a command and read the response).
  6. I'm done looking at ftp-get. I want to find something that has to do with passwords.
  7. ftp-password doesn't take a password, only a url, so the url must have the password already. I try "ftp://user:pwd@ftp.server.com/" >ftp-url inspect and verify that indeed the password is gotten from the URL itself.
  8. Tried "ftp://user:pwd@ftp.server.com/folder/file.ext" ftp-get - got an error saying it had trouble saving the file to disk - permission was denied. This makes sense since I never specified a local path to save the file to, but I see the error says it tried to save the file to my root folder. I suspect this is set in some dynamic variable, but I have no clue really. I need to find out where this function tries to save the files it GETs, or how it builds the local path.
  9. Drilled down ftp-get > (ftp-get) - saw it uses but otherwise it's a dead-end. I'll have to walk the code to see exactly what is fed to .
  10. Walked the code and found out it uses "file.ext" for the local-path. This doesn't look right, unless does more than meets the eye.
  11. Looked at the docs for , it doesn't mention anything helpful to me. I look at the source for it down below and click on normalize-path - aha! The docs say this function prepends current-directory to its argument. I did suspect this was going to be implicitly handled by a dynamic variable.
  12. Tried "/Users/user1/Desktop/" current-directory [ "ftp://user:pwd@ftp.server.com/folder/file.ext" ] with-variable and it worked fine.


I hope this helps.