this repo has no description
1#!/usr/bin/env ruby
2# generated by rubinjam v0.7.1 -- https://github.com/grosser/rubinjam
3module Rubinjam
4 LIBRARIES = {
5 "pru/core_ext/array" => "class Array\n # http://madeofcode.com/posts/74-ruby-core-extension-array-sum\n def sum(method = nil, &block)\n if block_given?\n raise ArgumentError, \"You cannot pass a block and a method!\" if method\n inject(0) { |sum, i| sum + yield(i) }\n elsif method\n inject(0) { |sum, i| sum + i.send(method) }\n else\n inject(0) { |sum, i| sum + i }\n end\n end unless method_defined?(:sum)\n\n def mean(*args, &block)\n sum(*args, &block) / size.to_f\n end unless method_defined?(:mean)\n\n def grouped\n group_by { |x| x }\n end unless method_defined?(:grouped)\n\n def counted\n grouped.sort_by{|d, f| -1 * f.size }.map{|d, f| \"\#{d} : \#{f.size}\" }\n end unless method_defined?(:counted)\nend\n",
6 "pru/version" => "module Pru\n VERSION = \"0.2.1\"\nend\n",
7 "pru" => "require 'pru/core_ext/array'\n\nmodule Pru\n class << self\n def map(io, code)\n String.class_eval <<-RUBY, __FILE__, __LINE__ + 1\n def _pru(i)\n \#{code}\n end\n RUBY\n\n i = 0\n io.each_line do |line|\n i += 1\n line.chomp!\n result = line._pru(i) or next\n\n case result\n when true then yield line\n when Regexp then yield line if line =~ result\n else yield result\n end\n end\n end\n\n def reduce(array, code)\n Array.class_eval <<-RUBY, __FILE__, __LINE__ + 1\n def _pru\n \#{code}\n end\n RUBY\n array._pru\n end\n end\nend\n",
8 "rubinjam/internal" => "module Rubinjam\n ROOT = File.expand_path(\"../\", __FILE__) << \"/rubinjam/\"\n\n class << self\n def normalize_file(file)\n return file unless file.start_with?(\"/\")\n if file.start_with?(ROOT)\n file.sub(ROOT, \"\")\n else\n file.split('/lib/').last\n end\n end\n\n def file_from_nesting(mod, const)\n if file = mod.rubinjam_autload[const]\n return [mod, file]\n end\n\n nesting(mod.name)[1..-1].detect do |mod|\n file = mod.rubinjam_autload[const]\n break [mod, file] if file\n end\n end\n\n # this does not reflect the actual Module.nesting of the caller,\n # but it should be close enough\n def nesting(name)\n nesting = []\n namespace = name.split(\"::\")\n namespace.inject(Object) do |base, n|\n klass = base.const_get(n)\n nesting << klass\n klass\n end\n nesting.reverse\n end\n end\n\n module ModuleAutoloadFix\n def self.included(base)\n base.class_eval do\n def rubinjam_autload\n @rubinjam_autload ||= {}\n end\n\n alias autoload_without_rubinjam autoload\n def autoload(const, file)\n normalized_file = Rubinjam.normalize_file(file)\n if Rubinjam::LIBRARIES[normalized_file]\n rubinjam_autload[const] = normalized_file\n else\n autoload_without_rubinjam(const, file)\n end\n end\n\n alias const_missing_without_rubinjam const_missing\n def const_missing(const)\n # do not load twice / go into infitire loops\n @rubinjam_tried_const_missing ||= {}\n if @rubinjam_tried_const_missing[const]\n return const_missing_without_rubinjam(const)\n end\n @rubinjam_tried_const_missing[const] = true\n\n # try to find autoload in current module or nesting\n nesting, file = Rubinjam.file_from_nesting(self, const)\n if file\n require file\n nesting.const_get(const)\n else\n const_missing_without_rubinjam(const)\n end\n end\n end\n end\n end\n\n module BaseAutoloadFix\n def self.included(base)\n base.class_eval do\n alias autoload_without_rubinjam autoload\n\n def autoload(const, file)\n normalized_file = Rubinjam.normalize_file(file)\n if Rubinjam::LIBRARIES[normalized_file]\n require normalized_file\n else\n autoload_without_rubinjam(const, file)\n end\n end\n end\n end\n end\nend\n\nModule.send(:include, Rubinjam::ModuleAutoloadFix)\ninclude Rubinjam::BaseAutoloadFix\n\ndef require(file)\n normalized_file = Rubinjam.normalize_file(file)\n if code = Rubinjam::LIBRARIES[normalized_file]\n return if code == :loaded\n eval(code, TOPLEVEL_BINDING, \"rubinjam/\#{normalized_file}.rb\")\n Rubinjam::LIBRARIES[normalized_file] = :loaded\n else\n super\n end\nend\n"
9 }
10end
11eval(Rubinjam::LIBRARIES.fetch("rubinjam/internal"), TOPLEVEL_BINDING, "rubinjam")
12#!/usr/bin/env ruby
13require 'optparse'
14
15# enable local usage from cloned repo
16root = File.expand_path("../..", __FILE__)
17$LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
18
19require 'pru'
20
21usage = nil
22options = {}
23
24OptionParser.new do |opts|
25 opts.banner = <<-BANNER.gsub(/^ /, "")
26 Pipeable Ruby
27
28 Use ruby in your pipes, forget about grep / sed / awk / wc ...
29
30 Map works on each line as String
31 Reduce works on all lines as Array (optional or via -r)
32
33 Usage:
34 something | pru 'map'
35 something | pru 'map' 'reduce'
36 something | pru '' 'reduce'
37 something | pru --reduce 'reduce'
38
39 Options:
40 BANNER
41 opts.on("-r", "--reduce CODE","reduce via CODE") {|code| options[:reduce] = code }
42 opts.separator ''
43 opts.on('-I', '--libdir DIR', 'Add DIR to load path') { |dir| $LOAD_PATH << dir }
44 opts.on('--require LIB', 'Require LIB (also comma-separated)') { |lib| lib.split(',').each{|l| require l } }
45 opts.on('-i', '--inplace-edit FILE', 'Edit FILE inplace') { |file| options[:file] = file }
46 opts.separator ''
47 opts.on("-h", "--help","Show this.") { puts opts; exit }
48 opts.on('-v', '--version','Show Version'){ require 'pru/version'; puts Pru::VERSION; exit}
49 usage = opts
50end.parse!
51
52if ARGV.empty? && options.empty? # no arguments -> show usage
53 puts usage
54 exit
55end
56
57abort "Too many arguments, see --help" if ARGV.size > 2
58
59map, reduce = ARGV
60reduce ||= options[:reduce]
61map = 'true' if !map || map.empty?
62
63if options[:file]
64 output_lines = []
65 input = File.read(options[:file])
66 newline = input[/\r\n|\r|\n/]
67 trailing_newline = (input =~ /#{newline}\Z/)
68else
69 input = $stdin
70end
71
72collector = lambda do |line|
73 if output_lines
74 output_lines << line
75 else
76 begin
77 puts(line)
78 rescue Errno::EPIPE
79 exit 0
80 end
81 end
82end
83
84if reduce
85 results = []
86 Pru.map(input, map) { |out| results << out }
87 collector.call Pru.reduce(results, reduce)
88else
89 Pru.map(input, map) { |out| collector.call out }
90end
91
92if options[:file]
93 content = output_lines.join(newline)
94 content << newline if trailing_newline
95 File.write options[:file], content
96end