kennethreitz-archive / procs

Python, Processes, and Prana.
225 stars 7 forks source link

Idea: Use __or__ for chaining #2

Open rconradharris opened 10 years ago

rconradharris commented 10 years ago

For the common case linking stdout to stdin of another process, we could use the 'pipe' syntax from shells by overloading the __or__ method.

Part of me thinks this is way too clever (in a bad way)... the other half thinks this would be really awesome/elegant.

Just an example:

class PipeCommand(object):
    def __init__(self, cmd):
        self.cmd = cmd
    def __repr__(self):
        return self.cmd
    def __or__(self, other):
        return PipeCommand('|'.join([self.cmd, other.cmd]))                                                                                                                                                        

def run(cmd):
    return PipeCommand(cmd)

print run('cat') | run('wc -l')
rubik commented 10 years ago

+1 it really resembles the already established shell syntax, so why not?

shrayasr commented 10 years ago

+1 this feels too good to be true. It does resemble the shell syntax a lot and makes a lot of sense to do it, but we end up overloading the __or__ operator which just leaves me thinking about the right way.

Since this is for humans, i guess we can afford to break some rules?

geerk commented 10 years ago

Why not just use plumbum?:

>>> chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"]
>>> print chain
/bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l
>>> chain()
u'13\n'
rconradharris commented 10 years ago

@geerk Interesting! Didn't know about that.

kennethreitz commented 10 years ago

I was considering something like this as well. I was thinking of this syntax, however:

>>> uptime.stdout >> cowsay.stdin

I like the pipe idea. Fitting, due to the name of the library :)

Either way, we need a method first that works, then we can look at making something like this, maybe :)

shrayasr commented 10 years ago

I was considering something like this as well. I was thinking of this syntax, however:

>>> uptime.stdout >> cowsay.stdin

HMMM. If we are doing something like this, then the | makes more sense IMO.

Either way, we need a method first that works, then we can look at making something like this, maybe :)

Agreed :+1: This is syntactic sugar

ssebastianj commented 10 years ago

And maybe the chain could be indexable:

>>> print(chain)
>>> <process('uptime') | process('cowsay')>
>>> print(chain[0])
>>> <process('uptime')>
>>> chain[0] = process('uname')
>>> print(chain)
>>> <process('uname') | process('cowsay')>
hjwp commented 10 years ago

For the curious, I had a crack at getting the | / __or__ thing working: https://github.com/kennethreitz/procs/pull/10