Class: Protocol::URL::Absolute

Inherits:
Relative
  • Object
show all
Defined in:
lib/protocol/url/absolute.rb

Overview

Represents an absolute URL with scheme and/or authority. Examples: "https://example.com/path", "//cdn.example.com/lib.js", "http://localhost/"

Instance Attribute Summary collapse

Attributes inherited from Relative

#The fragment identifier., #The query string component., #fragment, #path, #query

Instance Method Summary collapse

Methods inherited from Relative

#==, #===, #The path component of the URL.=, #as_json, #equal?, #fragment?, #hash, #inspect, #local_path, #normalize!, #query?, #to_json

Constructor Details

#initialize(scheme, authority, path = "/", query = nil, fragment = nil) ⇒ Absolute

Initialize a new absolute URL.



20
21
22
23
24
25
26
# File 'lib/protocol/url/absolute.rb', line 20

def initialize(scheme, authority, path = "/", query = nil, fragment = nil)
	@scheme = scheme
	@authority = authority
	
	# Initialize the parent Relative class with the path component
	super(path, query, fragment)
end

Instance Attribute Details

#authorityObject

Returns the value of attribute authority.



43
44
45
# File 'lib/protocol/url/absolute.rb', line 43

def authority
  @authority
end

#schemeObject

Returns the value of attribute scheme.



40
41
42
# File 'lib/protocol/url/absolute.rb', line 40

def scheme
  @scheme
end

#The authority component.(authoritycomponent.) ⇒ Object (readonly)



43
# File 'lib/protocol/url/absolute.rb', line 43

attr_accessor :authority

#The URL scheme.(URLscheme.) ⇒ Object (readonly)



40
# File 'lib/protocol/url/absolute.rb', line 40

attr_accessor :scheme

Instance Method Details

#+(other) ⇒ Object

Combine this absolute URL with a relative reference according to RFC 3986 Section 5.

Examples:

Resolve a relative path.

base = Absolute.new("https", "example.com", "/documents/reports/")
relative = Relative.new("summary.pdf")
result = base + relative
result.to_s  # => "https://example.com/documents/reports/summary.pdf"

Navigate to parent directory.

base = Absolute.new("https", "example.com", "/documents/reports/2024/")
relative = Relative.new("../../archive/")
result = base + relative
result.to_s  # => "https://example.com/documents/archive/"


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/protocol/url/absolute.rb', line 75

def +(other)
	case other
	when Absolute
		# If other is already absolute with a scheme, return it as-is:
		return other if other.scheme
		# Protocol-relative URL: inherit scheme from base:
		return Absolute.new(@scheme, other.authority, other.path, other.query, other.fragment)
	when Relative
		# Already a Relative, use directly.
	when String
		other = URL[other]
		# If parsing resulted in an Absolute URL, handle it:
		if other.is_a?(Absolute)
			return other if other.scheme
			# Protocol-relative URL: inherit scheme from base:
			return Absolute.new(@scheme, other.authority, other.path, other.query, other.fragment)
		end
	else
		raise ArgumentError, "Cannot combine Absolute URL with #{other.class}"
	end
	
	# RFC 3986 Section 5.3: Component Recomposition
	# At this point, other is a Relative URL
	
	# Check for special cases first:
	if other.path.empty?
		# Empty path - could be query-only or fragment-only reference:
		if other.query
			# Query replacement: use base path with new query:
			Absolute.new(@scheme, @authority, @path, other.query, other.fragment)
		else
			# Fragment-only: keep everything from base, just change fragment:
			Absolute.new(@scheme, @authority, @path, @query, other.fragment || @fragment)
		end
	else
		# Relative path: merge with base path:
		path = @path.join(other.path)
		Absolute.new(@scheme, @authority, path, other.query, other.fragment)
	end
end

#<=>(other) ⇒ Object

Compare this URL with another for sorting purposes.



159
160
161
# File 'lib/protocol/url/absolute.rb', line 159

def <=>(other)
	to_ary <=> other.to_ary
end

#append(buffer = String.new) ⇒ Object

Append the absolute URL to the given buffer.



117
118
119
120
121
# File 'lib/protocol/url/absolute.rb', line 117

def append(buffer = String.new)
	buffer << @scheme << ":" if @scheme
	buffer << "//" << @authority if @authority
	super(buffer)
end

#authority?Boolean

Check if the URL has a non-empty authority.

Returns:

  • (Boolean)


55
56
57
# File 'lib/protocol/url/absolute.rb', line 55

def authority?
	@authority and !@authority.empty?
end

#freezeObject

Freeze the URL and its direct components.



30
31
32
33
34
35
36
37
# File 'lib/protocol/url/absolute.rb', line 30

def freeze
	return self if frozen?
	
	@scheme.freeze
	@authority.freeze
	
	return super
end

#scheme?Boolean

Check if the URL has a non-empty scheme.

Returns:

  • (Boolean)


48
49
50
# File 'lib/protocol/url/absolute.rb', line 48

def scheme?
	@scheme and !@scheme.empty?
end

#to_aryObject

Convert the URL to an array representation.



151
152
153
# File 'lib/protocol/url/absolute.rb', line 151

def to_ary
	[@scheme, @authority, @path, @query, @fragment]
end

#to_sObject

Convert the URL to its string representation.



166
167
168
# File 'lib/protocol/url/absolute.rb', line 166

def to_s
	append
end

#with(scheme: @scheme, authority: @authority, path: nil, query: @query, fragment: @fragment, pop: true) ⇒ Object

Create a new Absolute URL with modified components.

Examples:

Change the scheme.

url = Absolute.new("http", "example.com", "/page")
secure = url.with(scheme: "https")
secure.to_s  # => "https://example.com/page"

Update the query string.

url = Absolute.new("https", "example.com", "/search", "query=ruby")
updated = url.with(query: "query=python")
updated.to_s  # => "https://example.com/search?query=python"


142
143
144
145
146
# File 'lib/protocol/url/absolute.rb', line 142

def with(scheme: @scheme, authority: @authority, path: nil, query: @query, fragment: @fragment, pop: true)
	path = @path.join(path, pop: pop) unless path.nil?
	
	self.class.new(scheme, authority, path || @path, query, fragment)
end