pru 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +7 -0
- data/Gemfile.lock +26 -0
- data/Rakefile +18 -0
- data/Readme.md +52 -0
- data/VERSION +1 -0
- data/bin/pru +41 -0
- data/lib/pru.rb +67 -0
- data/pru.gemspec +46 -0
- data/spec/pru_spec.rb +35 -0
- data/spec/spec_helper.rb +2 -0
- metadata +77 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.8.7)
|
11
|
+
rspec (2.4.0)
|
12
|
+
rspec-core (~> 2.4.0)
|
13
|
+
rspec-expectations (~> 2.4.0)
|
14
|
+
rspec-mocks (~> 2.4.0)
|
15
|
+
rspec-core (2.4.0)
|
16
|
+
rspec-expectations (2.4.0)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
rspec-mocks (2.4.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
jeweler
|
25
|
+
rake
|
26
|
+
rspec (~> 2)
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
task :default do
|
2
|
+
sh "rspec spec/"
|
3
|
+
end
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = 'pru'
|
9
|
+
gem.summary = "Pipeable Ruby"
|
10
|
+
gem.email = "michael@grosser.it"
|
11
|
+
gem.homepage = "http://github.com/grosser/#{gem.name}"
|
12
|
+
gem.authors = ["Michael Grosser"]
|
13
|
+
end
|
14
|
+
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler"
|
18
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
Pipeable Ruby
|
2
|
+
|
3
|
+
Use ruby in your pipes, forget about grep / sed / awk / wc ...
|
4
|
+
|
5
|
+
Sometimes pru is longer, but its easier to read/debug/refactor
|
6
|
+
and you only need to know pure ruby.
|
7
|
+
|
8
|
+
Install
|
9
|
+
=======
|
10
|
+
sudo gem install pru
|
11
|
+
|
12
|
+
Usage
|
13
|
+
=====
|
14
|
+
pru supports mapping and reducing.<br/><br/>
|
15
|
+
Map works on each line as String<br/>
|
16
|
+
Reduce works on all lines as Array<br/>
|
17
|
+
|
18
|
+
something | pru 'map' ['reduce']
|
19
|
+
something | pru -r 'reduce'
|
20
|
+
|
21
|
+
A few simple examples.<br/>
|
22
|
+
|
23
|
+
# grep --- all lines including foo
|
24
|
+
ls -al | grep foo
|
25
|
+
ls -al | pru 'include?("foo")'
|
26
|
+
|
27
|
+
# grep --- all lines including foo but not grep
|
28
|
+
ps -ef | grep foo | grep -v grep
|
29
|
+
ps -ef | pru 'include?("foo") and not include?("pru")'
|
30
|
+
|
31
|
+
# awk --- return second work
|
32
|
+
ls -al | awk '{print $2}'
|
33
|
+
ls -al | pru 'split(" ")[1]'
|
34
|
+
|
35
|
+
# awk --- count and average of all integers on second position
|
36
|
+
ls -al | awk '{ s += $2; } END {print "average" ,int(s/NR);print "count ",int(NR)}'
|
37
|
+
ls -al | pru 'split(" ")[1]' '"average #{mean(&:to_i)}\ncount #{size}"'
|
38
|
+
|
39
|
+
# wc --- count lines
|
40
|
+
ls -al | wc -l
|
41
|
+
ls -al | pru -r 'size'
|
42
|
+
|
43
|
+
# sed -- replace a 5 with five
|
44
|
+
ls -al | sed 's/5/five/'
|
45
|
+
ls -al | pru 'gsub(/5/,"five")'
|
46
|
+
|
47
|
+
|
48
|
+
Author
|
49
|
+
======
|
50
|
+
[Michael Grosser](http://grosser.it)<br/>
|
51
|
+
michael@grosser.it<br/>
|
52
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/pru
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
+
require 'pru'
|
7
|
+
|
8
|
+
options = {}
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = <<BANNER
|
11
|
+
Pipeable Ruby
|
12
|
+
|
13
|
+
Use ruby in your pipes, forget about grep / sed / awk / wc ...
|
14
|
+
|
15
|
+
Map works on each line as String
|
16
|
+
Reduce works on all lines as Array (optional or via -r)
|
17
|
+
|
18
|
+
Usage:
|
19
|
+
something | pru 'map' ['reduce']
|
20
|
+
something | pru -r 'reduce'
|
21
|
+
|
22
|
+
Options:
|
23
|
+
BANNER
|
24
|
+
opts.on("-r", "--reduce S","reduce via") {|s| options[:reduce] = s }
|
25
|
+
opts.on("-h", "--help","Show this.") { puts opts; exit }
|
26
|
+
opts.on('-v', '--version','Show Version'){ puts Pru::VERSION; exit}
|
27
|
+
end.parse!
|
28
|
+
|
29
|
+
map, reduce = ARGV
|
30
|
+
reduce ||= options[:reduce]
|
31
|
+
map = nil if map and map.empty?
|
32
|
+
|
33
|
+
if map and not reduce
|
34
|
+
Pru.map($stdin, map){|x| puts x }
|
35
|
+
elsif map and reduce
|
36
|
+
results = []
|
37
|
+
Pru.map($stdin, map){|x| results << x }
|
38
|
+
puts Pru.reduce(results, reduce)
|
39
|
+
elsif reduce
|
40
|
+
puts Pru.reduce($stdin.read.split("\n"), reduce)
|
41
|
+
end
|
data/lib/pru.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class Pru
|
2
|
+
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
3
|
+
|
4
|
+
def self.map(io, code)
|
5
|
+
io.readlines.each do |line|
|
6
|
+
result = line.instance_exec{ eval(code) }
|
7
|
+
if result == true
|
8
|
+
yield line
|
9
|
+
elsif result
|
10
|
+
yield result
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reduce(array, code)
|
16
|
+
array.instance_exec{ eval(code) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Object
|
21
|
+
unless defined? instance_exec # 1.9
|
22
|
+
module InstanceExecMethods #:nodoc:
|
23
|
+
end
|
24
|
+
include InstanceExecMethods
|
25
|
+
|
26
|
+
# Evaluate the block with the given arguments within the context of
|
27
|
+
# this object, so self is set to the method receiver.
|
28
|
+
#
|
29
|
+
# From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
|
30
|
+
def instance_exec(*args, &block)
|
31
|
+
begin
|
32
|
+
old_critical, Thread.critical = Thread.critical, true
|
33
|
+
n = 0
|
34
|
+
n += 1 while respond_to?(method_name = "__instance_exec#{n}")
|
35
|
+
InstanceExecMethods.module_eval { define_method(method_name, &block) }
|
36
|
+
ensure
|
37
|
+
Thread.critical = old_critical
|
38
|
+
end
|
39
|
+
|
40
|
+
begin
|
41
|
+
send(method_name, *args)
|
42
|
+
ensure
|
43
|
+
InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# http://madeofcode.com/posts/74-ruby-core-extension-array-sum
|
50
|
+
class Array
|
51
|
+
def sum(method = nil, &block)
|
52
|
+
if block_given?
|
53
|
+
raise ArgumentError, "You cannot pass a block and a method!" if method
|
54
|
+
inject(0) { |sum, i| sum + yield(i) }
|
55
|
+
elsif method
|
56
|
+
inject(0) { |sum, i| sum + i.send(method) }
|
57
|
+
else
|
58
|
+
inject(0) { |sum, i| sum + i }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Array
|
64
|
+
def mean(method = nil, &block)
|
65
|
+
sum(method, &block) / size.to_f
|
66
|
+
end
|
67
|
+
end
|
data/pru.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{pru}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Grosser"]
|
12
|
+
s.date = %q{2011-04-15}
|
13
|
+
s.default_executable = %q{pru}
|
14
|
+
s.email = %q{michael@grosser.it}
|
15
|
+
s.executables = ["pru"]
|
16
|
+
s.files = [
|
17
|
+
"Gemfile",
|
18
|
+
"Gemfile.lock",
|
19
|
+
"Rakefile",
|
20
|
+
"Readme.md",
|
21
|
+
"VERSION",
|
22
|
+
"bin/pru",
|
23
|
+
"lib/pru.rb",
|
24
|
+
"pru.gemspec",
|
25
|
+
"spec/pru_spec.rb",
|
26
|
+
"spec/spec_helper.rb"
|
27
|
+
]
|
28
|
+
s.homepage = %q{http://github.com/grosser/pru}
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
s.rubygems_version = %q{1.4.2}
|
31
|
+
s.summary = %q{Pipeable Ruby}
|
32
|
+
s.test_files = [
|
33
|
+
"spec/pru_spec.rb",
|
34
|
+
"spec/spec_helper.rb"
|
35
|
+
]
|
36
|
+
|
37
|
+
if s.respond_to? :specification_version then
|
38
|
+
s.specification_version = 3
|
39
|
+
|
40
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
41
|
+
else
|
42
|
+
end
|
43
|
+
else
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/spec/pru_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe Pru do
|
4
|
+
before :all do
|
5
|
+
@default = `ls -l | wc -l`
|
6
|
+
end
|
7
|
+
|
8
|
+
it "has a VERSION" do
|
9
|
+
Pru::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
10
|
+
end
|
11
|
+
|
12
|
+
it "maps" do
|
13
|
+
`ls -l | ./bin/pru 'include?("G")'`.split("\n").size.should == 2
|
14
|
+
end
|
15
|
+
|
16
|
+
it "maps and reduces" do
|
17
|
+
`ls -l | ./bin/pru 'include?("G")' 'size'`.should == "2\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "maps with empty string and reduces" do
|
21
|
+
`ls -l | ./bin/pru '' 'size'`.should == @default
|
22
|
+
end
|
23
|
+
|
24
|
+
it "reduces" do
|
25
|
+
`ls -l | ./bin/pru -r 'size'`.should == @default
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can sum" do
|
29
|
+
`echo 5 | ./bin/pru -r 'sum(&:to_i)'`.should == "5\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can mean" do
|
33
|
+
`echo 5 | ./bin/pru -r 'mean(&:to_i)'`.should == "5.0\n"
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pru
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michael Grosser
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-15 00:00:00 +02:00
|
19
|
+
default_executable: pru
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: michael@grosser.it
|
24
|
+
executables:
|
25
|
+
- pru
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- Gemfile
|
32
|
+
- Gemfile.lock
|
33
|
+
- Rakefile
|
34
|
+
- Readme.md
|
35
|
+
- VERSION
|
36
|
+
- bin/pru
|
37
|
+
- lib/pru.rb
|
38
|
+
- pru.gemspec
|
39
|
+
- spec/pru_spec.rb
|
40
|
+
- spec/spec_helper.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/grosser/pru
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.4.2
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Pipeable Ruby
|
75
|
+
test_files:
|
76
|
+
- spec/pru_spec.rb
|
77
|
+
- spec/spec_helper.rb
|