# converting to String
class DataStream < Hash
- def initialize(hsh={})
- self.replace(hsh)
+ # call-seq: new(text, hash)
+ #
+ # Create a new DataStream with text _text_ and attributes held by _hash_.
+ # Either parameter can be missing; if _text_ is missing, the text can be
+ # be defined in the _hash_ with a :text key.
+ #
+ def initialize(*args)
+ self.replace(args.pop) if Hash === args.last
+ self[:text] = args.first if args.length > 0
end
# Returns the :text key
alias :filter :call
end
- # This method processes the DataStream _stream_ with the filters _name_.
- # _name_ can be either a single Symbol (filter name), or an Array of
- # Symbols, in which case the output of each filter will be used as input
- # for the next
+ # call-seq:
+ # filter(filter1, filter2, ..., filterN, stream) -> stream
+ # filter(filter1, filter2, ..., filterN, text, hash) -> stream
+ # filter(filter1, filter2, ..., filterN, hash) -> stream
#
- def filter(name, stream={})
+ # This method processes the DataStream _stream_ with the filters <i>filter1</i>,
+ # <i>filter2</i>, ..., _filterN_, in sequence (the output of each filter is used
+ # as input for the next one.
+ # _stream_ can be provided either as a DataStream or as a String and a Hash
+ # (see DataStream.new).
+ #
+ def filter(*args)
@filters ||= {}
- names = (Symbol === name ? [name] : name.dup)
- ds = (DataStream === stream ? stream : DataStream.new(stream))
+ if Hash === args.last
+ # the stream is a Hash, check if the previous element is not a Symbol
+ if Symbol === args[-2]
+ ds = DataStream.new(args.pop)
+ else
+ ds = DataStream.new(*args.slice!(-2, 2))
+ end
+ else
+ # the stream is just whatever else
+ ds = DataStream.new(args.pop)
+ end
+ names = args.dup
return ds if names.empty?
# check if filters exist
missing = names - @filters.keys
fs.inject(ds) { |mid, f| mid = f.call(mid) }
end
+ # This method returns the global filter name for filter _name_
+ # in group _group_
+ def global_filter_name(name, group=nil)
+ (group ? "#{group}.#{name}" : name.to_s).intern
+ end
+
+ # This method checks if the bot has a filter named _name_ (in group
+ # _group_)
+ def has_filter?(name, group=nil)
+ @filters.key?(global_filter_name(name, group))
+ end
+
+ # This method checks if the bot has a filter group named _name_
+ def has_filter_group?(name)
+ @filter_group.key?(name)
+ end
+
# This method is used to register a new filter
- def register_filter(name, &block)
+ def register_filter(name, group=nil, &block)
raise "No block provided" unless block_given?
@filters ||= {}
- @filters[name.to_sym] = DataFilter.new &block
+ tlkey = global_filter_name(name, group)
+ key = name.to_sym
+ if has_filter?(tlkey)
+ debug "Overwriting filter #{tlkey}"
+ end
+ @filters[tlkey] = DataFilter.new(&block)
+ if group
+ gkey = group.to_sym
+ @filter_group ||= {}
+ @filter_group[gkey] ||= {}
+ if @filter_group[gkey].key?(key)
+ debug "Overwriting filter #{key} in group #{gkey}"
+ end
+ @filter_group[gkey][key] = @filters[tlkey]
+ end
+ end
+
+ # This method is used to retrieve the filter names (in a given group)
+ def filter_names(group=nil)
+ if group
+ gkey = group.to_sym
+ return [] unless defined? @filter_group and @filter_group.key?(gkey)
+ return @filter_group[gkey].keys
+ else
+ return [] unless defined? @filters
+ return @filters.keys
+ end
+ end
+
+ # This method is used to retrieve the filter group names
+ def filter_groups
+ return [] unless defined? @filter_group
+ return @filter_group.keys
end
# This method clears the filter list and installs the identity filter
def clear_filters
@filters ||= {}
@filters.clear
+
+ @filter_group ||= {}
+ @filter_group.clear
+
register_filter(:identity) { |stream| stream }
end
end