Giter Club home page Giter Club logo

lazy_files's Introduction

LazyFiles(v0.0.4)

warning: This software was last left in an alpha stage. Some of the APIs listed below are yet to be implemented, or were lost due to me barely knowing how to use git at the time. Use at your own caution.

A Library to make File-Handling in Ruby simple(r).

Installation

Add this line to your application's Gemfile:

gem 'lazy_files'

And then execute:

$ bundle

Or install it yourself as:

$ gem install lazy_files

Usage

Lazy.ls #=> [<LazyDir:lib>,<LazyDir:spec>,<LazyFile:README.md>, ... ]
Lazy.ls.each do |entry|
  puts entry.basename if entry.file? && entry.size > 0
end

prints...

Gemfile
Gemfile.lock
lazy_files.gemspec
LICENSE
Rakefile
README.md

Lazy::File

LazyFiles runs off of the idea of a File wrapper I call a Lazy::File. To create a Lazy::File simply call Lazy.file

Lazy.file('readme.md') #=> <LazyFile:readme.md>

A Lazy::File stores an absolute reference to your file, so you do not lose the file reference when you change directories

lazy = Lazy.file('README.md')
norm = File.open('README.md')

# cd into tmp/
Lazy.dir('tmp') do
  lazy.path #=> /home/michael/code/lazy_files/README.md
  norm.path #=> will raise an error
end

Unlike the File object, an IOStream is not opened when a Lazy::File is created. This allows you to store references to your files without using up buffers or file descripters.

file = Lazy.file('hello.txt')
file.stream             #=> nil
file.puts 'hello world'
file.stream             #=> <File:hello.txt>
file.close              #=> true
file.stream             #=> nil

IMPORTANT if you have never worked with an IOStream before there is an important concept to take hold of. When you open an IOStream you are sectioning off a buffer. This means that any stream left open will leak memory and file descriptors! Even though Ruby eventually closes the stream through garbage collection, its always good practice to close your streams after you're done with them.

With a Lazy::File you can close it with #close.

file = Lazy.file('hello.txt')
file.puts 'stuff...'
file.close #=> will close the stream and reset file#stream to nil

Just like with a File you can also quickly open and close a file by passing Lazy#file a block.

file = LazyFile.file('hello.txt') do |f|
  f.print 'hello_world'
end
file.closed? #=> true

A Lazy::File is nothing but a reference. The file must already exist for you to reference it.

Lazy.ls #=> []
Lazy.file('nofile.txt') #=> nil

if you want to create a file, call the mkfile method.

Lazy.mkfile('nofile.txt') #=> <LazyFile:nofile.txt>
Lazy.ls #=> [<LazyDir:nofile.txt>]

Lazy::Dir

A Lazy::Dir works very similar to a Lazy::File

Lazy.dir('docs')     #=> <LazyDir:docs>
Lazy.mkdir('newdir') #=> <LazyDir:newdir>

You can cd into a directory by passing a block.

Lazy.pwd   #=> /
Lazy.dir('docs') do
  Lazy.pwd #=> /docs
end

or use the cd method

dir = Lazy.dir('docs')
dir.cd do |d|
  d #=> <LazyDir:/docs>
  Lazy.pwd #=> /docs
end

Lazy.pwd   #=> /
dir.cd
Lazy.pwd   #=> /docs

You can also use Lazy::cd.

Lazy.cd('docs') do
  Lazy.pwd #=> /docs
end

If you for some odd reason you want to open a stream to your LazyDir, you can do it the same way you would in a normal Dir

dir = dir('docs')
dir.open
dir.tell
dir.read
dir.close

Command-Line Utils

  • wd/pwd - returns a Lazy::Dir for the working directory
  • mkfile - creates a new file and returns a Lazy::File
  • mkdir - creates a new directory and returns a Lazy::Dir
  • ls - returns an array of all items in the working directory in their Lazy form

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

lazy_files's People

Contributors

webdesserts avatar

Watchers

 avatar  avatar

lazy_files's Issues

Pointer Movement methods

Look into adding Vim style pointer movement methods as mentioned in #12. See if its viable or even beneficial.

Research Dirs and how they differ from File IOs

Since I looked into File IOs I now have a much better understanding of how they run and why they work the way they do. It looks like Dirs are similar but I need to make sure I know what I'm getting into. Research!

Lazy.cd

Just like Dir.chdir

Lazy.cd( '/' ) #=> <LazyDir:/>
Lazy.cd( '/' ) do |dir|
  dir.path #=> '/'
end

rename #io to #stream

As found out while pursuing this question, Dirs are not IOs, but just streams. Also open and close and many of the other basic methods you would use on an IOstream are more so attributes of Streams than they are specific to IOs. Thats why I think using #stream rather than #io would be the correct use of terms.

file = Lazy.file('hello_world', 'w')
file.stream #=> <File:hello_world>

Lazy::recursively

This method should allow you to pass a block that will be recursively executed inside all directories nested under the working directory.

Lazy.recursively do |wd|
  wd #would be the LazyDir of your working directory
end

should be able to set a limit on the maximum depth of nested directories the method reaches into

# this would execute the script in the wd as well as once in all directories
#1 level down. 
Lazy.recursively( limit: 1 ) { |wd| ... }

There should be a copy of this method on the LazyDir class

Lazy.dir('/').recursively() { |wd| ... }

There should also be a recursive option for many of the libraries methods.

Lazy.ls( recursive: true ) #=> [ ... ]
Lazy.count( recursive: true ) #=> 5786

Lazy.ls

Returns an array of everything in the current directory and returns either a LazyFile or LazyDir for each item. Should not return default directories like .. or ..

Lazy.ls() #=> [<LazyDir:lib>, <LazyDir:spec>, <LazyFile:README.md>]
Lazy.ls[0] #=> <LazyDir:src>
Lazy.ls.each do |item|
  puts item.path
end
Lazy.ls( ftype: 'dir' ) #=> [<LazyDir:lib>, <LazyDir:spec>]
Lazy.ls( ext: 'md' ) #=> [<LazyFile:README.md>]

Basic functionality should probably be finished by v0.1.0 while filtering should probably be implemented around v0.3.0

Lazy.pwd

self explanatory

#basically just like Dir.pwd but returns a LazyDir
Lazy.pwd() #=> <LazyDir:code>

Clean up specs

Try to use more subject and let calls to prep most of the logic. Factories will probably also help. See if you can use lambdas or helper methods as well.

Break up classes

There is currently a lot of logic that is duplicated between File and Dir. I think a Lazy::Path or Lazy::Stream should be attempted. This should also help reduce duplication in specs as well.

Lazy::count & LazyDir#count

::count should return the number of items in the working directory. It should basically be the equivalent of Lazy.ls.length but should skip the process of creating objects for each entry.

Lazy.count() #=> 7

it should allow filtering options.

Lazy.count( ext: 'html' ) #=> 3
Lazy.count( ftype: 'dir' ) #=> 2

There should also be a LazyDir#count method that should work the same, just it should return a count for that directory rather than the working directory.

Lazy.dir( '/' ).count #=> a really large number

Print and Put directly from object.

One of the common reasons you create a file is to tack on a few characters. It seems kinda over kill to pop open a block for this so I suggest that a puts and print method is added to the LazyFile class.

f = Lazy.file( 'readme.md' )
f.print 'hello'
f.print ' world'
f.read #=> "hello world"
f.puts 'goodbye world'
f.read #=> "hello worldgoodbye world/n"

How to create a File/Dir vs how to store one

In the original File class, if you wanted to create a file, you would have to File.open( 'file.txt' ) {}. This is the same command you would use is you wanted to open an existing file as well. I feel that this can be confusing and doesn't allow for you to try to store a file reference and check for existence at the same time. I think something like the following would serve developers better:

Lazy.file( 'README.md' ) #=> nil
Lazy.mkfile( 'README.md' ) #=> <LazyFile:README.md>
Lazy.file( 'README.md' ) #=> <LazyFile:README.md>

I think ::mkfile makes sense considering there's a ::mkdir equivalent. I believe there's still a place for a touch method but creating files was not its main purpose, updating timestamps was.

The ::mkfile method should also allow you to pass a block and write in it, like so:

Lazy.mkfile( 'README' ) do |f|
  f.puts 'TODO: write a description of your app'
end

LazyFile #ext & #ext?

#ext should basically be your File.extname equivilant

Lazy.file( 'index.html' ).ext() #=> 'html'

#ext? should return a boolean based on whether the #ext matches the provided extension or not.

Lazy.file( 'index.html' ).ext?( 'html' ) #=> false

not sure if Lazy.file( 'README.md' ).ext?( 'markdown' ) should return true or not right now. Maybe this is a good spot for a `file.fformat?('markdown') instead, but that probably will be hard to maintain.

Append methods

Pull from ideas mentioned in #12 and create append methods for LazyFiles.

Start moving "Readme Wishlist" over to their own issues.

Now that I'm starting to migrate the repository onto Github, I need the README to actually reflect the current state of the program. Also, now that major progress is being made, the README should be updated with every change to the API. This is a library that I want other developers to use. The documentation needs to be top priority.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.