Ejemplo
Show that T::Struct.from_hash bypasses the runtime type enforcement that the .new constructor applies
sha256:49b3a0ec0dc911830c4cf62df5ff6bb54e1006a59d4d7830a843495fc1ee8400
PUBLISHED
L3_CONTRACT_PASS
MIT-0
Caso
- Objetivo
- Show that T::Struct.from_hash bypasses the runtime type enforcement that the .new constructor applies HOW
- Paquetes
- sorbet-runtime 0.6.13427
- Entorno
- ruby
- Creado
- 2026-08-17T02:49:00Z
Lo que suele suponerse
Because T::Struct declares prop types and the .new constructor raises TypeError when a value does not match, from_hash — the documented deserialization path — applies the same check and raises on mismatched types.
El autor de la muestra anotó aquí lo que un desarrollador o un modelo esperaría. El contrato de abajo es lo que realmente se ejecutó.
Contrato
- T::Struct.from_hash accepts a String value for a prop declared Integer and returns it unchanged without raising TypeError, while T::Struct.new raises TypeError for the identical input — proving that the deserialization path skips the sig-based check the constructor applies
- assert ConnectionRecord.from_hash('port' => '5432').port == '5432'
- assert ConnectionRecord.new(port: '5432') raises TypeError matching /Can't set ConnectionRecord\.port/
- assert from_hash with an unknown string key silently discards it rather than raising
- assert from_hash with symbol keys treats them as absent and raises RuntimeError about nil deserialization
- assert from_hash with Integer elements inside a T::Array[String] prop returns them unchanged — element types are not checked
Archivos
- Gemfile
- Gemfile.lock
- NOTES.md
- csx.json
- src/model.rb
- test/contract.rb
Descargar el artefacto verificado (tar.gz): los bytes exactos con los que se ejecutó el contrato
Seeder de origen
Recibos de verificación
- ruby 3 · CONTAINER_RUN · compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS · rubygems@1 · 2026-08-17 · ed25519:d91480838ac982c9