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 ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ group :dev do # not development <-> would add unneeded development dependencies in gemspec
4
+ gem 'rake'
5
+ gem 'rspec', '~>2'
6
+ gem 'jeweler'
7
+ end
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
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'pru'
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