Skip to content

Give native HTTP value types Ruby value semantics #126

Description

@ZilvinasKucinskas

Priority: P2

Describe the issue

Several native wrapper types represent values but still use object identity for equality or default object formatting. This makes equivalent responses compare unequal and makes public constants awkward to log, store in a Set, or use as Hash keys.

Tested with wreq 1.2.4:

first = response.status
second = response.status

first.as_int                 # => 201
first == second              # => false
first.eql?(second)           # => false
first.hash == second.hash    # => false
first.respond_to?(:to_i)     # => false

response.version == response.version       # => true
response.version.eql?(response.version)     # => false

Wreq::Method::GET.to_s
# => "#<Wreq::Method:0x...>"

Wreq::Version already implements ==, demonstrating the intended value-object direction, but eql? and hash are not aligned with it.

Proposed Ruby behavior

status = response.status
status.to_i                          # => 201
status == response.status            # => true
status.eql?(response.status)         # => true
{status => :created}[response.status] # => :created

Wreq::Method::GET.to_s   # => "GET"
Wreq::Method::GET.to_sym # => :get
  • StatusCode: value-based ==, eql?, and hash; to_i (with as_int retained).
  • Version: keep value-based == and add matching eql?/hash.
  • Method and SameSite: add meaningful to_s; retain the already useful Profile#to_s and Platform#to_s behavior.
  • Enum-like Method, Profile, Platform, and SameSite: value equality, eql?, and hash; add to_sym only where there is an unambiguous Ruby name.
  • Constants and immutable values should be frozen/shareable where the native implementation permits it.
  • Keep Response#code as the existing direct Integer API.

Do not make StatusCode#eql?(201) true: equality and Hash semantics should remain internally consistent. Callers can use to_i or Response#code when comparing with an Integer.

Acceptance criteria

  • Two wrappers for the same native value compare with == and eql? and have equal hashes.
  • Different values do not compare equal.
  • Values work as Hash keys and Set members.
  • Method#to_s returns an HTTP method token without an object ID.
  • StatusCode#to_i returns the numeric status and as_int remains compatible.
  • Tests cover every public enum/value family and cross-type comparisons.

Ruby ecosystem precedent

Ruby value objects follow the ==/eql?/hash contract. HTTPX exposes status as an Integer, while http.rb's response-status object implements numeric conversion, comparison, and value equality. A native wrapper should be no less predictable than the value it wraps.

wreq-python's HTTP wrappers are frozen value classes and provide rich comparison for status codes, demonstrating that the underlying native values can support language-appropriate semantics.

Relevant wreq-ruby source

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions