1#
2#   shell/filter.rb -
3#       $Release Version: 0.7 $
4#       $Revision: 38201 $
5#       by Keiju ISHITSUKA(keiju@ruby-lang.org)
6#
7# --
8#
9#
10#
11
12class Shell #:nodoc:
13  # Any result of command exection is a Filter.
14  #
15  # This class includes Enumerable, therefore a Filter object can use all
16  # Enumerable
17  # facilities.
18  #
19  class Filter
20    include Enumerable
21
22    def initialize(sh)
23      @shell = sh         # parent shell
24      @input = nil        # input filter
25    end
26
27    attr_reader :input
28
29    def input=(filter)
30      @input = filter
31    end
32
33    # call-seq:
34    #   each(record_separator=nil) { block }
35    #
36    # Iterates a block for each line.
37    def each(rs = nil)
38      rs = @shell.record_separator unless rs
39      if @input
40        @input.each(rs){|l| yield l}
41      end
42    end
43
44    # call-seq:
45    #   < source
46    #
47    # Inputs from +source+, which is either a string of a file name or an IO
48    # object.
49    def < (src)
50      case src
51      when String
52        cat = Cat.new(@shell, src)
53        cat | self
54      when IO
55        self.input = src
56        self
57      else
58        Shell.Fail Error::CantApplyMethod, "<", to.class
59      end
60    end
61
62    # call-seq:
63    #   > source
64    #
65    # Outputs from +source+, which is either a string of a file name or an IO
66    # object.
67    def > (to)
68      case to
69      when String
70        dst = @shell.open(to, "w")
71        begin
72          each(){|l| dst << l}
73        ensure
74          dst.close
75        end
76      when IO
77        each(){|l| to << l}
78      else
79        Shell.Fail Error::CantApplyMethod, ">", to.class
80      end
81      self
82    end
83
84    # call-seq:
85    #   >> source
86    #
87    # Appends the output to +source+, which is either a string of a file name
88    # or an IO object.
89    def >> (to)
90      begin
91        Shell.cd(@shell.pwd).append(to, self)
92      rescue CantApplyMethod
93        Shell.Fail Error::CantApplyMethod, ">>", to.class
94      end
95    end
96
97    # call-seq:
98    #   | filter
99    #
100    # Processes a pipeline.
101    def | (filter)
102      filter.input = self
103      if active?
104        @shell.process_controller.start_job filter
105      end
106      filter
107    end
108
109    # call-seq:
110    #   filter1 + filter2
111    #
112    # Outputs +filter1+, and then +filter2+ using Join.new
113    def + (filter)
114      Join.new(@shell, self, filter)
115    end
116
117    def to_a
118      ary = []
119      each(){|l| ary.push l}
120      ary
121    end
122
123    def to_s
124      str = ""
125      each(){|l| str.concat l}
126      str
127    end
128
129    def inspect
130      if @shell.debug.kind_of?(Integer) && @shell.debug > 2
131        super
132      else
133        to_s
134      end
135    end
136  end
137end
138