Giter VIP home page Giter VIP logo

Comments (15)

empjustine avatar empjustine commented on July 23, 2024 1

dir['*'].search(/foo/) seems to describe better what you want to do.

As a breaking change, home.ls should be an alias to home[*] IMHO.

The problem is that you're considering file names must be sane, and you can "simply newline split them", you're gonna have a bad time.

Using glob syntax and the Array it returns will (most of the time) free you from having to deal with those dangerous minutae.

If you don't, use at least ls -print0, and split using "\0", as good bash people should.

-print0
      True; print the full file name on the standard output, followed by a 
      null character (instead of the newline character that -print uses).  
      This allows file  names  that  contain  newlines or other types of white 
      space to be correctly interpreted by programs that process the find 
      output.  This option corresponds to the -0 option of xargs.

*not available on all flavours of ls such as busybox ls.

from rush.

s-mage avatar s-mage commented on July 23, 2024

Is there a ruby way to do this?

 λ → home.ls # this would return String
 λ → home.ls.split("\n").select { |x| x =~ /Do/ }                                                                                                                                                                                  
["Documents", "Downloads"]   # this is how I would do it now.
λ → home.ls.e :grep, :foo                                                                                                                                                                                                         
sh: 2: bin: not found
sh: 3: chrome: not found
sh: 4: Desktop: not found
sh: 5: desktop.png: not found
sh: 6: Documents: not found
sh: 7: Downloads: not found
...
# This is what happened  when I exec grep on string :)

from rush.

Leo2807 avatar Leo2807 commented on July 23, 2024

Maybe we could write a pipe function that takes a variable list of arguments.

from rush.

matthiasbeyer avatar matthiasbeyer commented on July 23, 2024

@Leo2807

A commandline call would then look like this:

pipe (pipe (pipe ls grep("foo")) grep("bar")) less

vs.

ls | grep foo | grep bar | less

What do you think now?

from rush.

s-mage avatar s-mage commented on July 23, 2024

I think it's more suitable to lisp :) Plus it's more ugly than in bash.
How pipes work in bash? There is stdout from one process that is adding to another as first or last argument?

from rush.

Leo2807 avatar Leo2807 commented on July 23, 2024

Sorry if I was unclear, I meant a variable length argument list. It would look like this:

pipe :ls, :grep, :less

It would still need a way to add arguments though.

from rush.

matthiasbeyer avatar matthiasbeyer commented on July 23, 2024

@Leo2807

pipe ls: "-a" , grep: ["-E", /foo/], :less

Would be much better.


Okay, I'm stopping the trolling here now. This problem is rather hard to accomplish, yes. I would personally go like this:

  1. Have a normal bash syntax for pipes (foo | bar)
  2. Parse the commandline input into subcommands (AST parsing in its simplest form)
  3. Call the commands and connect their stdin/stdout

So basically just what the bash does. We could prettify this with some neat keywords or something:

ls -> grep -E bar -> less
ls err> grep foo out> less

or whatever.

from rush.

s-mage avatar s-mage commented on July 23, 2024

http://stackoverflow.com/a/9834134/1685746 ah, it pushes that data to stdin. Oookay, I'll think how to implement that in ruby.

# for example
home.pipe :ls, %w(grep hello), :less
# this maybe work too
home.ls.pipe { |x| grep x "hello" }.pipe(&:less)

I'm not sure which one is better.

from rush.

s-mage avatar s-mage commented on July 23, 2024

Now I'm really thinking about how clojure deals with all that braces. They have threading macro that work
like this: https://clojuredocs.org/clojure.core/-%3E
What if we could do the same in ruby (but with some other name, since -> is lambda here.

home.ls.pipe { |x| grep x "hello" }.pipe(&:less)
# what if this would be equal
home.pipe_chain
  :ls,
  -> (x) { grep x "hello" },
  -> (x) { less '-R' x }

# no, it's ugly.

from rush.

RomanHargrave avatar RomanHargrave commented on July 23, 2024

@s-mage I'm not sure what you are referring to by "braces". I assume you are referring to two different approaches to pipelining here:

  1. Compositional form - chaining method calls to create a command object
  2. Functional form - passing multiple command objects in the order they need to be piped

In my opinion, the first option would be superior, as a shell needs to allow piping more than just STDOUT, which the second notation could not allow for. This could easily be accounted for in the first by either modifying the pipe() method to support an optional 'fd' parameter for the file descriptor that is to be piped to the next process, or by adding another method 'pipefd(fd, command)' that supports specifying the file descriptor.

In terms of what fd should be, it would optimally be an integer for best compatibility with the underlying implementation.

from rush.

s-mage avatar s-mage commented on July 23, 2024

Hi, I'm back.

FYI, ruby supports pipelines via Open3 lib: http://ruby-doc.org/stdlib-2.0.0/libdoc/open3/rdoc/Open3.html

So one possible solution is just use Open3.pipeline, but it's not very convenient.

Another way is build my own pipeline based on popen3 (or maybe popen2). In the end it should look like this

home                 # box
  .ls('-lah')        # string
  .grep 'opensource' # string

from rush.

s-mage avatar s-mage commented on July 23, 2024
 λ → Open3.capture2("grep 'opensource'", stdin_data: home.ls('-lah'))                                                                                                                                                              
["drwxr-xr-x  44 s    s    4,0K окт.  16 18:20 opensource\n",
 #<Process::Status: pid 12124 exit 0>]

Example with Open3

from rush.

s-mage avatar s-mage commented on July 23, 2024

So I'd monkeypatch String class method_missing method, but it causes errors (I've just tried). Maybe I should create my own class and wrap every command output? Or is there more elegant solution?

from rush.

Leo2807 avatar Leo2807 commented on July 23, 2024

I think that could work. Something like this:

class Pipe
    ...
    def method_missing(cmd, args*)
        ...
    end
end

pipe = Pipe.new someDir
print pipe.ls.grep('cow').hexdump

Or a more bash-like syntax:

class Pipe
    ...
    def |(pipe)
        ...
    end
end

ls = Pipe.new 'ls'
grep = Pipe.new 'grep'
hexdump = Pipe.new 'hexdump'

ls | grep('cow') | hexdump

from rush.

s-mage avatar s-mage commented on July 23, 2024

@lostinblue Why not file.write 'string' ? https://github.com/s-mage/rush/wiki/Handbook%3A-File-Contents

from rush.

Related Issues (9)

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.