Class: Lutaml::Uml::PackagePath

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/uml/package_path.rb

Overview

Immutable value object representing a UML package path.

A package path consists of one or more segments separated by “::”. Examples:

- "ModelRoot"
- "ModelRoot::Conceptual Models"
- "ModelRoot::Conceptual Models::i-UR::urf"

PackagePath objects are immutable and frozen after initialization.

Constant Summary collapse

SEPARATOR =
"::"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ PackagePath

Create a new PackagePath from a string or array.

The package path string or array of segments

Parameters:

  • path (String, Array<String>)

Raises:

  • (ArgumentError)

    if path is nil



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/lutaml/uml/package_path.rb', line 24

def initialize(path) # rubocop:disable Metrics/MethodLength
  if path.nil?
    raise ArgumentError, "Path cannot be nil"
  end

  # Handle both string and array inputs
  @segments = if path.is_a?(Array)
                path.reject { |s| s.nil? || s.empty? }.freeze
              else
                # String input - allow empty string
                # Filter out empty segments from string paths
                path.split(SEPARATOR).reject(&:empty?).freeze
              end
  @path = @segments.join(SEPARATOR).freeze

  freeze
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



17
18
19
# File 'lib/lutaml/uml/package_path.rb', line 17

def path
  @path
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Check equality with another PackagePath.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

    true if equal



178
179
180
# File 'lib/lutaml/uml/package_path.rb', line 178

def ==(other)
  other.is_a?(PackagePath) && @path == other.path
end

#absolute?Boolean

Check if this is an absolute path (starts with “ModelRoot”).

Returns:

  • (Boolean)

    true if absolute, false otherwise



62
63
64
# File 'lib/lutaml/uml/package_path.rb', line 62

def absolute?
  segments.first == "ModelRoot"
end

#child(name) ⇒ PackagePath

Create a child path by appending a segment.

Examples:

PackagePath.new("ModelRoot::i-UR").child("urf")
# => PackagePath("ModelRoot::i-UR::urf")

Parameters:

  • name (String)

    The segment name to append

Returns:

  • (PackagePath)

    A new PackagePath with the appended segment



100
101
102
# File 'lib/lutaml/uml/package_path.rb', line 100

def child(name)
  self.class.new("#{@path}#{SEPARATOR}#{name}")
end

#depthInteger

Get the depth of this path.

Depth is counted as number of separators (segments.size - 1).

Examples:

PackagePath.new("ModelRoot").depth # => 0
PackagePath.new("ModelRoot::i-UR").depth # => 1
PackagePath.new("ModelRoot::i-UR::urf").depth # => 2

Returns:

  • (Integer)

    The depth of the path (0 for single segment)



75
76
77
78
79
# File 'lib/lutaml/uml/package_path.rb', line 75

def depth
  return 0 if segments.empty?

  segments.size - 1
end

#empty?Boolean

Check if this path is empty.

Returns:

  • (Boolean)

    true if empty (no segments)



163
164
165
# File 'lib/lutaml/uml/package_path.rb', line 163

def empty?
  @segments.empty?
end

#hashInteger

Generate hash code for this path.

Returns:

  • (Integer)

    The hash code



187
188
189
# File 'lib/lutaml/uml/package_path.rb', line 187

def hash
  @path.hash
end

#matches_glob?(pattern) ⇒ Boolean

Check if this path matches a glob pattern.

Supports:

- "*" to match a single segment
- "**" to match zero or more segments

Examples:

path = PackagePath.new("ModelRoot::i-UR::urf")
path.matches_glob?("ModelRoot::*::urf") # => true
path.matches_glob?("ModelRoot::**") # => true
path.matches_glob?("ModelRoot::*") # => false

Parameters:

  • pattern (String)

    The glob pattern

Returns:

  • (Boolean)

    true if the path matches the pattern



155
156
157
158
# File 'lib/lutaml/uml/package_path.rb', line 155

def matches_glob?(pattern)
  pattern_segments = pattern.split(SEPARATOR)
  match_segments(segments, pattern_segments)
end

#parentPackagePath?

Get the parent path.

Examples:

PackagePath.new("ModelRoot::i-UR::urf").parent
# => PackagePath("ModelRoot::i-UR")

Returns:

  • (PackagePath, nil)

    The parent path, or nil if at root



87
88
89
90
91
# File 'lib/lutaml/uml/package_path.rb', line 87

def parent
  return nil if segments.size <= 1

  self.class.new(segments[0...-1])
end

#relative_to(base_path_string) ⇒ PackagePath

Get the relative path from a base path.

The base path to calculate relative to

Examples:

path = PackagePath.new("ModelRoot::i-UR::urf")
path.relative_to("ModelRoot::i-UR")
# => PackagePath("urf")

Parameters:

Returns:

  • (PackagePath)

    The relative path, or self if not relative



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/lutaml/uml/package_path.rb', line 113

def relative_to(base_path_string)
  base = if base_path_string.is_a?(PackagePath)
           base_path_string
         else
           self.class.new(base_path_string)
         end
  return self unless starts_with?(base)

  remaining = segments[base.segments.size..]
  return self.class.new("") if remaining.empty?

  self.class.new(remaining)
end

#segmentsArray<String>

Get the segments of this path.

Examples:

PackagePath.new("ModelRoot::i-UR::urf").segments
# => ["ModelRoot", "i-UR", "urf"]

Returns:

  • (Array<String>)

    The path segments



48
49
50
# File 'lib/lutaml/uml/package_path.rb', line 48

def segments
  @segments
end

#separatorString

Get the separator used in package paths.

Returns:

  • (String)

    The separator (“::”)



55
56
57
# File 'lib/lutaml/uml/package_path.rb', line 55

def separator
  SEPARATOR
end

#starts_with?(other) ⇒ Boolean

Check if this path starts with another path.

Examples:

path = PackagePath.new("ModelRoot::i-UR::urf")
path.starts_with?("ModelRoot::i-UR") # => true
path.starts_with?("ModelRoot::CityGML") # => false

Parameters:

  • other (PackagePath, String)

    The path to check against

Returns:

  • (Boolean)

    true if this path starts with other



135
136
137
138
139
140
# File 'lib/lutaml/uml/package_path.rb', line 135

def starts_with?(other)
  other_path = other.is_a?(PackagePath) ? other : self.class.new(other)
  return false if other_path.segments.size > segments.size

  segments[0...other_path.segments.size] == other_path.segments
end

#to_sString

Convert to string representation.

Returns:

  • (String)

    The path as a string



170
171
172
# File 'lib/lutaml/uml/package_path.rb', line 170

def to_s
  @path
end