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 path component of the URL., #The query string component., #fragment, #path, #query

Instance Method Summary collapse

Methods inherited from Relative

#==, #===, #as_json, #equal?, #fragment?, #hash, #inspect, #normalize!, #query?, #to_json, #to_local_path

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 (readonly)

Returns the value of attribute authority.



32
33
34
# File 'lib/protocol/url/absolute.rb', line 32

def authority
  @authority
end

#schemeObject (readonly)

Returns the value of attribute scheme.



29
30
31
# File 'lib/protocol/url/absolute.rb', line 29

def scheme
  @scheme
end

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



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

attr :authority

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



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

attr :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/"


64
65
66
67
68
69
70
71
72
73
74
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
# File 'lib/protocol/url/absolute.rb', line 64

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.expand(@path, other.path)
		Absolute.new(@scheme, @authority, path, other.query, other.fragment)
	end
end

#<=>(other) ⇒ Object

Compare this URL with another for sorting purposes.



146
147
148
# File 'lib/protocol/url/absolute.rb', line 146

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

#append(buffer = String.new) ⇒ Object

Append the absolute URL to the given buffer.



106
107
108
109
110
# File 'lib/protocol/url/absolute.rb', line 106

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)


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

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

#scheme?Boolean

Check if the URL has a non-empty scheme.

Returns:

  • (Boolean)


37
38
39
# File 'lib/protocol/url/absolute.rb', line 37

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

#to_aryObject

Convert the URL to an array representation.



138
139
140
# File 'lib/protocol/url/absolute.rb', line 138

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

#to_sObject

Convert the URL to its string representation.



153
154
155
# File 'lib/protocol/url/absolute.rb', line 153

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"


131
132
133
# File 'lib/protocol/url/absolute.rb', line 131

def with(scheme: @scheme, authority: @authority, path: nil, query: @query, fragment: @fragment, pop: true)
	self.class.new(scheme, authority, Path.expand(@path, path, pop), query, fragment)
end