Class: NRSER::Sys::Env::Path

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/nrser/sys/env/path.rb

Overview

TODO:

document NRSER::Env::Path class.

Constant Summary collapse

SEPARATOR =

Character used to separate path entries in string format.

Returns:

':'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#assoc_by, #assoc_to, #count_by, #enumerate_as_values, #find_bounded, #find_map, #find_only, #only, #only!, #slice?, #try_find

Constructor Details

#initialize(source, env_key: nil) ⇒ Path

Instantiate a new ‘NRSER::Env::Path`.



171
172
173
174
175
# File 'lib/nrser/sys/env/path.rb', line 171

def initialize source, env_key: nil
  @env_key = env_key.to_s.freeze
  @source = source.dup.freeze
  @value = self.class.normalize source
end

Instance Attribute Details

#env_keynil | String (readonly)

Key for the value in ‘ENV` that the object represents. This is set when loading from `ENV` and used to know where to write when saving back to it.

Returns:



150
151
152
# File 'lib/nrser/sys/env/path.rb', line 150

def env_key
  @env_key
end

#sourcenil | String | #each_index (readonly)

The object that was originally provided at construction.

Returns:

  • (nil | String | #each_index)


157
158
159
# File 'lib/nrser/sys/env/path.rb', line 157

def source
  @source
end

#valueHamster::Vector<String> (readonly)

The actual internal list of paths.

Returns:



164
165
166
# File 'lib/nrser/sys/env/path.rb', line 164

def value
  @value
end

Class Method Details

.from_ENV(env_key) ⇒ return_type

TODO:

Document from_env method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



137
138
139
# File 'lib/nrser/sys/env/path.rb', line 137

def self.from_ENV env_key
  new ENV[env_key.to_s], env_key: env_key
end

.matches_pattern?(path, *patterns) ⇒ Boolean

See if a ‘path` matches any of `patterns`.

Short-circuits as soon as a match is found (so patterns may not all be tested).

Parameters:

  • path (String)

    Path to test against.

  • *patterns (Array<String | Proc<String=>Boolean> | Regexp>)

    Patterns to test:

    • ‘String` - test if it and `path` are equal (`==`)

    • ‘Proc<String=>Boolean>` - call with `path` and evaluate result as Boolean.

    • ‘Regexp` - test if it matches `path` (`=~`)

Returns:

  • (Boolean)

    ‘true` if any of `patterns` match `path`.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/nrser/sys/env/path.rb', line 108

def self.matches_pattern? path, *patterns
  patterns.any? do |pattern|
    case pattern
    when String
      path == pattern
    when Proc
      pattern.call path
    when Regexp
      path =~ pattern
    else
      raise TypeError.new binding.erb <<-END
        Each `*patterns` arg should be String, Proc or Regexp, found:
        
            <%= pattern.pretty_inspect %>
        
      END
    end
  end
end

.normalize(source) ⇒ return_type

TODO:

Document normalize method.

Returns @todo Document return value.

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (return_type)

    @todo Document return value.



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
# File 'lib/nrser/sys/env/path.rb', line 54

def self.normalize source
  paths = if source.nil?
    []
  
  elsif source.is_a?( String )
    source.to_s.split SEPARATOR
    
  elsif NRSER.array_like?( source )
    # Flatten it if supported
    source = source.flatten if source.respond_to?( :flatten )
    
    # Stringify each segment, split them and concat results
    source.flat_map { |entry| entry.to_s.split SEPARATOR }
  
  else
    raise ArgumentError.new binding.erb <<-END
      Expected a string or an "array-like" source, found:
      
          <%= source.pretty_inspect %>
      
    END
  end
  
  Hamster::Vector.new paths.
    # Get rid of empty paths
    reject( &:empty? ).
    # Get rid of duplicates
    uniq.
    # Freeze all the strings
    map( &:freeze )
end

Instance Method Details

#append(source) ⇒ self

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (self)


205
206
207
208
209
210
211
212
213
214
215
# File 'lib/nrser/sys/env/path.rb', line 205

def append source
  # Normalize the new source to a flat array of strings
  paths = self.class.normalize source
  
  # The new value is the current paths with the new paths appended, with
  # any paths in the current path removed from the new ones (de-duplication)
  @value = (@value + paths).uniq
  
  # Return self for chain-ability
  self
end

#each(&block) ⇒ self, Enumerator

Support for Enumerable mixin. Yields each path in order.

Specifically, proxies to Hamster::Vector#each

Parameters:

  • &block (nil | Proc<(String)=>*>)

    When present, block will be called once for each string path in this object. First path is most prominent, down to least last.

Returns:

  • (self)

    When ‘&block` is provided.

  • (Enumerator)

    When ‘&block` is omitted.

See Also:



273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/nrser/sys/env/path.rb', line 273

def each &block
  if block
    # Proxy for yielding
    @value.each &block
    
    # Return self for chain-ability
    self
  else
    # Return the {Enumerator} from the vector
    @value.each
  end
end

#insert(source, before: nil, after: nil) ⇒ Object



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/nrser/sys/env/path.rb', line 221

def insert source, before: nil, after: nil
  paths = self.class.normalize source
  
  before_index = if before
    @value.find_index do |path|
      self.class.matches_pattern? path, *before
    end
  end
  
  after_index = if after
    index = @value.rindex { |path| self.class.matches_pattern? path, *after }
    index += 1 if index
  end
  
  insert_index = if after_index && before_index
    # Make sure the conditions don't conflict with each other
    if after_index > before_index
      raise "Conflicting bounds!"
    end
    
    # Insert as far "down" the path as allowed
    [before_index, after_index].max
  else
    # Use the one that is not `nil`, or insert at the end if they both are
    before_index || after_index || @value.length
  end
  
  @value = @value.insert( insert_index, *paths ).uniq
  
  self
end

#prepend(source) ⇒ self Also known as: unshift, >>, push, <<

Parameters:

  • source (nil | String | #each_index)

    Path source.

Returns:

  • (self)


185
186
187
188
189
190
191
192
193
194
195
# File 'lib/nrser/sys/env/path.rb', line 185

def prepend source
  # Normalize the new source to a flat array of strings
  paths = self.class.normalize source
  
  # The new value is the normalized paths followed by the current paths
  # with the new ones removed (de-duplication)
  @value = (paths + @value).uniq
  
  # Return self for chain-ability
  self
end

#to_aArray<String>

The string paths in a new stdlib ‘Array`. Mutating this array will have no effect on the Env::Path data.

Returns:



301
302
303
# File 'lib/nrser/sys/env/path.rb', line 301

def to_a
  @value.to_a
end

#to_sString

The paths joined with ‘:’.

Returns:



291
292
293
# File 'lib/nrser/sys/env/path.rb', line 291

def to_s
  @value.join SEPARATOR
end