Class: Protocol::URL::Relative
- Inherits:
-
Object
- Object
- Protocol::URL::Relative
- Includes:
- Comparable
- Defined in:
- lib/protocol/url/relative.rb
Overview
Represents a relative URL, which does not include a scheme or authority.
Instance Attribute Summary collapse
-
#fragment ⇒ Object
Returns the value of attribute fragment.
-
#path ⇒ Object
Returns the value of attribute path.
-
#query ⇒ Object
Returns the value of attribute query.
- #The fragment identifier.(fragmentidentifier.) ⇒ Object readonly
- #The query string component.(querystringcomponent.) ⇒ Object readonly
Instance Method Summary collapse
-
#+(other) ⇒ Object
Combine this relative URL with another URL or path.
-
#<=>(other) ⇒ Object
Compare this URL with another for sorting purposes.
-
#==(other) ⇒ Object
Check structural equality by comparing components.
-
#===(other) ⇒ Object
Check string equality, useful for case statements.
-
#append(buffer = String.new, explicit: false) ⇒ Object
Append the relative URL to the given buffer.
-
#as_json ⇒ Object
Convert the URL to a JSON-compatible representation.
-
#equal?(other) ⇒ Boolean
Check if this URL is equal to another URL by comparing components.
- #fragment? ⇒ Boolean
-
#freeze ⇒ Object
Freeze the URL and its direct components.
-
#hash ⇒ Object
Compute a hash value for the URL based on its components.
-
#initialize(path, query = nil, fragment = nil) ⇒ Relative
constructor
Initialize a new relative URL.
-
#inspect ⇒ Object
Generate a human-readable representation for debugging.
-
#local_path(root) ⇒ Object
(also: #to_local_path)
Resolve the URL path beneath a local filesystem root.
-
#normalize! ⇒ Object
Normalize the encoded path and simplify its structure.
- #query? ⇒ Boolean
-
#relative_to(base) ⇒ Object
Express this URL relative to the given base path.
- #The path component of the URL.=(pathcomponentoftheURL. = (value)) ⇒ Object
-
#to_ary ⇒ Object
Convert the URL to an array representation.
-
#to_json ⇒ Object
Convert the URL to JSON.
-
#to_s(explicit: false) ⇒ Object
Convert the URL to its string representation.
-
#with(path: nil, query: @query, fragment: @fragment, pop: true) ⇒ Object
Create a new Relative URL with modified components.
Constructor Details
Instance Attribute Details
#fragment ⇒ Object
Returns the value of attribute fragment.
52 53 54 |
# File 'lib/protocol/url/relative.rb', line 52 def fragment @fragment end |
#path ⇒ Object
Returns the value of attribute path.
39 40 41 |
# File 'lib/protocol/url/relative.rb', line 39 def path @path end |
#query ⇒ Object
Returns the value of attribute query.
49 50 51 |
# File 'lib/protocol/url/relative.rb', line 49 def query @query end |
#The fragment identifier.(fragmentidentifier.) ⇒ Object (readonly)
52 |
# File 'lib/protocol/url/relative.rb', line 52 attr_accessor :fragment |
#The query string component.(querystringcomponent.) ⇒ Object (readonly)
49 |
# File 'lib/protocol/url/relative.rb', line 49 attr_accessor :query |
Instance Method Details
#+(other) ⇒ Object
Combine this relative URL with another URL or path.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/protocol/url/relative.rb', line 91 def +(other) case other when Absolute # Relative + Absolute: the absolute URL takes precedence # You can't apply relative navigation to an absolute URL other when Relative # Relative + Relative: merge paths directly self.class.new( @path.join(other.path), other.query, other.fragment ) when String # Relative + String: parse and combine self + URL[other] else raise ArgumentError, "Cannot combine Relative URL with #{other.class}" end end |
#<=>(other) ⇒ Object
Compare this URL with another for sorting purposes.
219 220 221 |
# File 'lib/protocol/url/relative.rb', line 219 def <=>(other) to_ary <=> other.to_ary end |
#==(other) ⇒ Object
Check structural equality by comparing components.
227 228 229 |
# File 'lib/protocol/url/relative.rb', line 227 def ==(other) to_ary == other.to_ary end |
#===(other) ⇒ Object
Check string equality, useful for case statements.
235 236 237 |
# File 'lib/protocol/url/relative.rb', line 235 def ===(other) to_s === other end |
#append(buffer = String.new, explicit: false) ⇒ Object
Append the relative URL to the given buffer. The path, query, and fragment are expected to already be properly encoded.
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/protocol/url/relative.rb', line 179 def append(buffer = String.new, explicit: false) append_path(buffer, explicit: explicit) if @query and !@query.empty? buffer << "?" << @query end if @fragment and !@fragment.empty? buffer << "#" << @fragment end return buffer end |
#as_json ⇒ Object
Convert the URL to a JSON-compatible representation.
252 253 254 |
# File 'lib/protocol/url/relative.rb', line 252 def as_json(...) to_s end |
#equal?(other) ⇒ Boolean
Check if this URL is equal to another URL by comparing components.
211 212 213 |
# File 'lib/protocol/url/relative.rb', line 211 def equal?(other) to_ary == other.to_ary end |
#fragment? ⇒ Boolean
71 72 73 |
# File 'lib/protocol/url/relative.rb', line 71 def fragment? @fragment and !@fragment.empty? end |
#freeze ⇒ Object
Freeze the URL and its direct components.
28 29 30 31 32 33 34 35 36 |
# File 'lib/protocol/url/relative.rb', line 28 def freeze return self if frozen? @path.freeze @query.freeze @fragment.freeze return super end |
#hash ⇒ Object
Compute a hash value for the URL based on its components.
203 204 205 |
# File 'lib/protocol/url/relative.rb', line 203 def hash to_ary.hash end |
#inspect ⇒ Object
Generate a human-readable representation for debugging.
266 267 268 |
# File 'lib/protocol/url/relative.rb', line 266 def inspect "#<#{self.class} #{to_s}>" end |
#local_path(root) ⇒ Object Also known as: to_local_path
Resolve the URL path beneath a local filesystem root.
59 60 61 |
# File 'lib/protocol/url/relative.rb', line 59 def local_path(root) @path.local_path(root) end |
#normalize! ⇒ Object
Normalize the encoded path and simplify its structure.
This modifies the URL in-place by normalizing and simplifying the path component:
- Decodes percent-encoded unreserved characters
- Uses uppercase hexadecimal digits for retained percent escapes
- Removes "." segments (current directory)
- Resolves ".." segments (parent directory)
- Collapses empty path segments represented by consecutive slashes
Normalization is intentionally lossy. Callers that need to preserve the original path structure should retain the parsed URL and avoid this method.
170 171 172 173 174 |
# File 'lib/protocol/url/relative.rb', line 170 def normalize! @path = @path.normalize.simplify return self end |
#query? ⇒ Boolean
66 67 68 |
# File 'lib/protocol/url/relative.rb', line 66 def query? @query and !@query.empty? end |
#relative_to(base) ⇒ Object
Express this URL relative to the given base path.
Already-relative paths are returned unchanged. Query and fragment components are preserved when converting a root-relative path.
142 143 144 145 146 147 148 149 150 |
# File 'lib/protocol/url/relative.rb', line 142 def relative_to(base) return self unless @path.absolute? if base.is_a?(Relative) base = base.path end return self.class.new(@path.relative(base), @query, @fragment) end |
#The path component of the URL.=(pathcomponentoftheURL. = (value)) ⇒ Object
39 |
# File 'lib/protocol/url/relative.rb', line 39 attr :path |
#to_ary ⇒ Object
Convert the URL to an array representation.
196 197 198 |
# File 'lib/protocol/url/relative.rb', line 196 def to_ary [@path, @query, @fragment] end |
#to_json ⇒ Object
Convert the URL to JSON.
259 260 261 |
# File 'lib/protocol/url/relative.rb', line 259 def to_json(...) as_json.to_json(...) end |
#to_s(explicit: false) ⇒ Object
Convert the URL to its string representation.
When explicit, same-directory references start with ./ so they can be
distinguished from non-URL values in a mixed grammar.
245 246 247 |
# File 'lib/protocol/url/relative.rb', line 245 def to_s(explicit: false) append(explicit: explicit) end |
#with(path: nil, query: @query, fragment: @fragment, pop: true) ⇒ Object
Create a new Relative URL with modified components.
129 130 131 132 133 |
# File 'lib/protocol/url/relative.rb', line 129 def with(path: nil, query: @query, fragment: @fragment, pop: true) path = @path.join(path, pop: pop) unless path.nil? self.class.new(path || @path, query, fragment) end |