summaryrefslogtreecommitdiff
path: root/lib/shell/filter.rb
blob: c1f4b28a45e48c7be0aec7b8683b91ad6bc07d81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# frozen_string_literal: false
#
#   shell/filter.rb -
#       $Release Version: 0.7 $
#       $Revision$
#       by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
#
#

class Shell #:nodoc:
  # Any result of command execution is a Filter.
  #
  # This class includes Enumerable, therefore a Filter object can use all
  # Enumerable
  # facilities.
  #
  class Filter
    include Enumerable

    def initialize(sh)
      @shell = sh         # parent shell
      @input = nil        # input filter
    end

    attr_reader :input

    def input=(filter)
      @input = filter
    end

    # call-seq:
    #   each(record_separator=nil) { block }
    #
    # Iterates a block for each line.
    def each(rs = nil)
      rs = @shell.record_separator unless rs
      if @input
        @input.each(rs){|l| yield l}
      end
    end

    # call-seq:
    #   < source
    #
    # Inputs from +source+, which is either a string of a file name or an IO
    # object.
    def < (src)
      case src
      when String
        cat = Cat.new(@shell, src)
        cat | self
      when IO
        self.input = src
        self
      else
        Shell.Fail Error::CantApplyMethod, "<", to.class
      end
    end

    # call-seq:
    #   > source
    #
    # Outputs from +source+, which is either a string of a file name or an IO
    # object.
    def > (to)
      case to
      when String
        dst = @shell.open(to, "w")
        begin
          each(){|l| dst << l}
        ensure
          dst.close
        end
      when IO
        each(){|l| to << l}
      else
        Shell.Fail Error::CantApplyMethod, ">", to.class
      end
      self
    end

    # call-seq:
    #   >> source
    #
    # Appends the output to +source+, which is either a string of a file name
    # or an IO object.
    def >> (to)
      begin
        Shell.cd(@shell.pwd).append(to, self)
      rescue CantApplyMethod
        Shell.Fail Error::CantApplyMethod, ">>", to.class
      end
    end

    # call-seq:
    #   | filter
    #
    # Processes a pipeline.
    def | (filter)
      filter.input = self
      if active?
        @shell.process_controller.start_job filter
      end
      filter
    end

    # call-seq:
    #   filter1 + filter2
    #
    # Outputs +filter1+, and then +filter2+ using Join.new
    def + (filter)
      Join.new(@shell, self, filter)
    end

    def to_a
      ary = []
      each(){|l| ary.push l}
      ary
    end

    def to_s
      str = ""
      each(){|l| str.concat l}
      str
    end

    def inspect
      if @shell.debug.kind_of?(Integer) && @shell.debug > 2
        super
      else
        to_s
      end
    end
  end
end