Tired of having a hard time working with files? Take a look at Fast...
require "fast" lib_dir = dir! :lib # Creates a new dir "lib" lib_dir["demo.txt"] = "I love creating files from a Hash-like API" # Creates lib/demo.txt containing the text lib_dir.list # => ['demo.txt'] file! "lib/empty.txt" # New file lib/empty.txt lib_dir.files do |path| puts path end # => demo.txt # empty.txt lib_dir.destroy dir? :lib # => false
...and finally is quite stable so you can use it if you wish so.
Fast is a DSL for file and dir handling focused in intuitivity and semantics. Fast is pure Ruby, don't relays on OS functions, so is a little slower but more portable.
gem install fast
Fast declares two sets of methods in its DSL:
dir :lib # The same as => Fast::Dir.new "lib" dir.delete! "demo" # The same as => Fast::Dir.new.delete! "demo" dir! :new_dir # The same as => Fast::Dir.new.create! :new_dir dir? :new_dir # The same as => Fast::Dir.new.exist? :new_dir
file "demo.txt" # The same as => Fast::File.new "demo.txt" file.copy "demo.txt", "new.txt" # The same as => # Fast::File.new.copy "demo.txt", "new.txt" file! "demo.txt" # The same as => Fast::File.new.create! "demo.txt" file? "demo.txt" # The same as => Fast::File.new.exist? "demo.txt"
Fast embraces the more straightforward view of files as strings of data and directories as arrays of files/directories. Why?
- It is more realistic in everyday usage
- It makes them more object-like (and thus, more friendly to OOP)
- It is more semantic
- Files as IOs are still accessible through the harder-to-use native Ruby API
Fast::Dir is a subclass of Array, usable as a hash, and Fast::File if a subclass of String.
In order to workaround that, you can require fast in a not-so-much DSL way:
require "fast/fast" Fast.file "myfile.txt" # The same as `file "myfile.txt"` Fast.dir! :lib # etc...
This is also the recommended form when using Fast in the context of a library.
Also: try to avoid using Fast in a library, because Fast is mostly semantic sugar and you want to avoid adding loading time just for the sake of having a couple of convenience methods. Fast is more fun when used for code sketching and simple scripts.
Quick notes (to self)
- Rename FilesystemObject: Item, CommonMethods, AbstractFile, FastHelpers (think!)
- Deliberate whether is a good idea to make Fast::Dir and Fast::File Multitons. (May be only when an absolute path is used)
- The path can be setted indirectly by any method of Fast::File instances, and the same works for Dir. This is fine because allows for very quick calls, but once an instance gets a path setted it should be fixed and raise an exception in case some other method call is trying to change it.
- Read bytes as binary ASCII-8BIT always and then try to perform an heuristic conversion, if there is any reasonable way to do it. Otherwise, leave it to the user. Google: "ruby string encode utf-8 ascii" for some good readings.
- Calls to #dirs and #files should delegate to a SubSetter
- Change the behaviour in the calls to #dirs and #files: return a new instance, with no @path setted.
- Change the behaviour in the initialization: call #list always if there's a path an the path matches an existing directory
- Allow for easy recursive calls (#list_all, #files_all, #dirs_all for example, think of better synonyms)
- Deliberate whether "#<<" should be kept in Fast::Dir and if it should be used as alias for merge
- An instance of Fast::Dir should be possible to be created from a Array. (pity I didn't specified an usage case)
- Add documentation to Patterns::Adapter::Fast::Dir
- Make Fast a REST client (well, use rest-client) in order to transparently use files and directories from a compliant REST server.
- Include REST methods: Dir#post, File#get, File#head, etc and equivalents for local files (prepare ground for Piano Rest)
- Allow Files to behave as Dirs with the right method calls
GPL License. Why other?
@ Xavier Via