Class: Humanized::Source

Inherits:
Object show all
Defined in:
lib/humanized/source.rb

Overview

A source lets you lookup,store and load data needed for humanization.

Constant Summary collapse

VALUE_KEY =
:_
NOT_NIL_LAMBDA =
lambda{|x| !x.nil? }

Instance Method Summary collapse

Constructor Details

#initialize(data = {}) ⇒ Source

Returns a new instance of Source.



26
27
28
29
30
31
# File 'lib/humanized/source.rb', line 26

def initialize(data = {})
  #TODO: data should maybe deep-copied
  @source = data
  @sync = Sync.new
  @loaded = Set.new
end

Instance Method Details

#<<(data) ⇒ Object

Stores the given data on the base.

Parameters:

See Also:



71
72
73
# File 'lib/humanized/source.rb', line 71

def <<(data)
  store([],data)
end

#get(query, options = {}) ⇒ String, ...

Retrieves data

Parameters:

  • query (Query, #each)

    a query containing the paths to search for

Returns:



100
101
102
103
104
105
106
107
108
# File 'lib/humanized/source.rb', line 100

def get(query, options = {})
  default = options[:default]
  accepts = options.fetch(:accepts,NOT_NIL_LAMBDA )
  query.each do |path|
    v = @source[path]
    return v if accepts.call(v)
  end
  return default
end

#inspectObject



134
135
136
# File 'lib/humanized/source.rb', line 134

def inspect
  "#<#{self.class.name}:#{self.object_id.to_s} | #{@source.size} key(s); loaded: #{@loaded.inspect}>"
end

#load(path, opts = {}) ⇒ Object

Loads a data-file or a dir of data-files.

Parameters:

  • path (String)

    to a dir or file

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :query (Query)

    the root query, where the loaded data will be stored ( default: Root )

  • :grep (String)

    a grep to be used when a dir is given ( default: ‘*/.*’ )

Returns:

  • self



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
# File 'lib/humanized/source.rb', line 40

def load(path,opts ={})
  options = {:query => Query::Root, :grep => '**/*.*'}.update(opts)
  if File.directory?(path)
    f = File.join(path,options[:grep])
    package('grep:' + f) do
      Dir[f].each do |file|
        package('file:'+file) do
          data = self.read_file(file)
          if data
            xpath = file[path.size..(-1-File.extname(file).size)].split('/')
            xpath.shift if xpath.first == ''
            xquery = options[:query]._(*xpath.map(&:to_sym))
            self.store(xquery.first,data)
          end
        end
      end
    end
  else
    package('file:'+path) do
      data = self.read_file(path)
      if data
        self.store(options[:query].first,data)
      end
    end
  end
  return self
end

#package(name) {|self| ... } ⇒ Object

This is method which will help you loading data once. It will load every package just one time.

Example

source = Source.new
10.times do
  source.package('base') do |s|
    s << {:base => { :data => 'more data'}} # <= This data will be only loaded once!
  end
end

Parameters:

Yields:

  • self

Yield Parameters:



88
89
90
91
92
93
94
95
# File 'lib/humanized/source.rb', line 88

def package(name)
  return nil if @loaded.include? name
  @sync.synchronize(Sync::EX){
    return nil if @loaded.include? name
    yield(self)
    @loaded << name
  }
end

#store(path, data) ⇒ Object

Stores data at the path

Parameters:

  • path (Array)

    a path to store the data at

  • data (Object)

    the data to store



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/humanized/source.rb', line 113

def store(path ,data)
  @sync.synchronize(Sync::EX){
    if data.kind_of? Hash
      data.each do |key, value|
        if key.kind_of? Array
          store( path + key, value)
          next
        end
        key = key.to_sym
        if key == VALUE_KEY
          store( path, value )
        else
          store( path + [key], value)
        end
      end
    else
      @source[path] = data
    end
  }
end