CodeSampleX

샘플

json 2.9.1: Parse and serialize Ruby data structures with JSON.[] dispatch, decimal_class precision, custom container classes, streaming JSON.dump depth checks, and core type additions

검증된 샘플 — gem json 2.9.1: Parse and serialize Ruby data structures with JSON.[] dispatch, decimal_class precision, custom container classes, streaming…

sha256:a87be603acbde77905b8b59ae00abe846be04ddcac05e754dcc29647170a50de

이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다. 통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다. MIT-0

실행 증거

선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.

증거 기준
서명된 컨트랙트 통과
검증 영수증
2
빌드한 서명 키
2
선언된 환경 ruby linux x64 ruby ruby rubygems

검증 실행 환경

환경 컨트랙트 단계 실행일
ruby 3 · linux debian/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · rubygems@1
2026-08-17
ruby 3 · linux debian/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · rubygems@1
2026-08-18

케이스

HOW
목표
Parse and serialize Ruby data structures with JSON.[] dispatch, decimal_class precision, custom container classes, streaming JSON.dump depth checks, and core type additions
패키지
심벌
  • JSON.[]
  • JSON.parse
  • JSON.dump
  • JSON.create_id
  • json/add/time
  • json/add/date
  • json/add/struct
  • json/add/set
  • json/add/symbol
환경
ruby
생성일
2026-08-17T12:28:09Z

컨트랙트

  1. assert JSON.[] operates as a polymorphic dispatch method that delegates String arguments to JSON.parse and non-String Ruby objects to JSON.generate
  2. assert JSON.parse with decimal_class: BigDecimal preserves exact arbitrary-precision decimal representations without IEEE 754 float rounding loss
  3. assert JSON.parse supports custom collection containers via array_class and object_class
  4. assert JSON.dump streams serialized output directly to IO destinations when provided and enforces strict recursion depth limits raising ArgumentError when exceeded
  5. assert requiring json/add core extensions enables bidirectional JSON serialization for Time, Date, Struct, Set, and Symbol types using create_additions: true
  6. assert JSON.create_id configures the addition type identifier attribute and setting custom values alters the tag matched during deserialization

파일

  • Gemfile
  • Gemfile.lock
  • NOTES.md
  • csx.json
  • src/json_features.rb
  • test/contract.rb

소스 아티팩트 내려받기 (tar.gz)

소스

Gemfile
source "https://rubygems.org"

gem "json", "2.9.1"
gem "bigdecimal"
Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    bigdecimal (4.1.2)
    json (2.9.1)

PLATFORMS
  ruby
  x64-mingw-ucrt

DEPENDENCIES
  bigdecimal
  json (= 2.9.1)

CHECKSUMS
  bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
  bundler (4.0.18) sha256=02d9a17429de1847b4e0c9f27a9ee4b20c0a74c0a641b4e77195d6019e3618ac
  json (2.9.1) sha256=d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11

BUNDLED WITH
  4.0.18
NOTES.md
# Ruby `json` Library: Dispatch, Precision, Containers, IO Streaming, and Core Type Additions

## 1. What `search_known_solution` answered
`search_known_solution` returned existing published samples:
- `sha256:872c9e461ccac83e7b19625704d8e2280fefb4903330c45f8b5925114ada2453`: Focused on `JSON.load` positional keyword-proc collision with `create_additions`, `max_nesting: 0` vs `max_nesting: false` depth limit bypasses, `freeze: true` deep immutability, and generator `script_safe` tag escaping.
- `sha256:bc062acc906536678976cf1c339f352acd1b7ab93a8126083d2e995f58c8816b`: Focused on `JSON.parse!` relaxed parsing limits, core additions for `Range`, `Regexp`, `Complex`, and `Rational`, custom `to_json` arity and `JSON::State` whitespace formatting.

This sample proves a distinct set of behaviors in the Ruby `json` library:
1. Polymorphic dispatch through `JSON.[]`: `JSON[string]` delegates to `JSON.parse`, while `JSON[object]` delegates to `JSON.generate`, forwarding optional configuration arguments.
2. Precision preservation with `decimal_class: BigDecimal`: Default parsing coerces fractional numbers to standard `Float` instances, truncating long decimal sequences; configuring `decimal_class: BigDecimal` preserves arbitrary-precision values exactly.
3. Custom collection parsing with `array_class` and `object_class`: Custom container subclasses can be designated to hold parsed arrays and objects.
4. `JSON.dump` IO destination streaming and recursion depth limit: Passing an `IO` (or `StringIO`) object streams serialized output directly to the destination and returns the stream instance; specifying a shallow recursion limit enforces depth checks and raises `ArgumentError` when exceeded.
5. Standard library additions: Requiring `json/add/time`, `json/add/date`, `json/add/struct`, `json/add/set`, and `json/add/symbol` enables bidirectional serialization with `"json_class"` metadata and `create_additions: true` restoration.
6. Tag configuration with `JSON.create_id`: Modifying `JSON.create_id` customizes the addition identifier key looked up during addition creation.

## 2. Pinned Version
- Pinned release: `pkg:gem/json@2.9.1`

## 3. Observed Behavior
- `JSON['{"service":"catalog"}']` returns a `Hash` (`{"service"=>"catalog"}`), whereas `JSON[{ service: "catalog" }]` returns a `String` (`"{\"service\":\"catalog\"}"`).
- Parsing `'{"val":0.12345678901234567890123456789}'` yields a `Float` with lost precision by default, but yields an exact `BigDecimal` matching the original decimal literal when `decimal_class: BigDecimal` is supplied.
- `JSON.parse(..., array_class: CustomArray, object_class: CustomObject)` populates the specified container types instead of generic `Array` and `Hash` instances.
- `JSON.dump(payload, io)` writes JSON to the IO stream and returns `io`, while `JSON.dump(deep_array, limit)` raises `ArgumentError: exceed depth limit` if nesting exceeds `limit`.
- Native `Time` instances serialize with seconds and nanoseconds (`{"json_class":"Time","s":...,"n":...}`); deserializing with `create_additions: true` recovers the exact `Time` instance with matching `.nsec`.
- Native `Date`, `Struct`, `Set`, and `Symbol` instances serialize to structured JSON hashes with `"json_class"` and reconstruct to identical Ruby objects when `create_additions: true` is active.
- Changing `JSON.create_id` to a custom string shifts addition deserialization to match only hashes containing that custom key.
csx.json
{"case":{"caseId":"case:sha256:cce90ff524e10afe1292b6b7dc75e7de763ddf949a34b0cc39679f55926584e7","contract":["assert JSON.[] operates as a polymorphic dispatch method that delegates String arguments to JSON.parse and non-String Ruby objects to JSON.generate","assert JSON.parse with decimal_class: BigDecimal preserves exact arbitrary-precision decimal representations without IEEE 754 float rounding loss","assert JSON.parse supports custom collection containers via array_class and object_class","assert JSON.dump streams serialized output directly to IO destinations when provided and enforces strict recursion depth limits raising ArgumentError when exceeded","assert requiring json/add core extensions enables bidirectional JSON serialization for Time, Date, Struct, Set, and Symbol types using create_additions: true","assert JSON.create_id configures the addition type identifier attribute and setting custom values alters the tag matched during deserialization"],"goal":"Parse and serialize Ruby data structures with JSON.[] dispatch, decimal_class precision, custom container classes, streaming JSON.dump depth checks, and core type additions","kind":"HOW","packages":["pkg:gem/json@2.9.1"],"schemaVersion":1,"symbols":["JSON.[]","JSON.parse","JSON.dump","JSON.create_id","json/add/time","json/add/date","json/add/struct","json/add/set","json/add/symbol"]},"contractCommand":["bundle","exec","ruby","test/contract.rb"],"environment":{"arch":"x64","ecosystem":"gem","executionContext":"ruby","language":"ruby","os":"linux","packageManager":"rubygems","runtime":"ruby","schemaVersion":1},"license":"MIT-0","packages":["pkg:gem/json@2.9.1"],"schemaVersion":1,"symbols":["JSON.[]","JSON.parse","JSON.dump","JSON.create_id","json/add/time","json/add/date","json/add/struct","json/add/set","json/add/symbol"],"verifierAdapter":"rubygems@1"}
src/json_features.rb
# frozen_string_literal: true

require "json"
require "bigdecimal"
require "stringio"
require "date"
require "json/add/time"
require "json/add/date"
require "json/add/struct"
require "json/add/set"
require "json/add/symbol"

module JsonFeatures
  # Custom Array container class for array_class option
  class CustomArray < Array
  end

  # Custom Hash container class for object_class option
  class CustomObject < Hash
  end

  # Polymorphic JSON gateway: parses strings and generates from objects
  def self.dispatch(input, *opts)
    JSON[input, *opts]
  end

  # Parses JSON with high decimal precision using BigDecimal
  def self.parse_exact_decimal(json_str)
    JSON.parse(json_str, decimal_class: BigDecimal)
  end

  # Parses JSON into customized collection types
  def self.parse_custom_containers(json_str, array_class: CustomArray, object_class: CustomObject)
    JSON.parse(json_str, array_class: array_class, object_class: object_class)
  end

  # Streams serialized JSON into an IO destination with optional recursion limit
  def self.dump_to_stream(object, io, limit = nil)
    if limit
      JSON.dump(object, io, limit)
    else
      JSON.dump(object, io)
    end
  end

  # Serializes to String enforcing depth limits
  def self.dump_with_depth_limit(object, limit)
    JSON.dump(object, limit)
  end
end
test/contract.rb
# frozen_string_literal: true

require "bundler/setup"
require_relative "../src/json_features"

def assert(condition, message = "Assertion failed")
  raise message unless condition
end

def assert_equal(expected, actual, message = nil)
  msg = message || "Expected #{expected.inspect}, got #{actual.inspect}"
  raise msg unless expected == actual
end

def assert_instance_of(klass, actual, message = nil)
  msg = message || "Expected instance of #{klass}, got #{actual.class}"
  raise msg unless actual.is_a?(klass)
end

def assert_raises(exception_klass)
  raised = false
  begin
    yield
  rescue exception_klass => e
    raised = true
    return e
  rescue => e
    raise "Expected #{exception_klass}, but got #{e.class} (#{e.message})"
  end
  raise "Expected #{exception_klass} to be raised, but nothing was raised"
end

# ---------------------------------------------------------------------------
# 1. Polymorphic JSON.[] gateway dispatch
# ---------------------------------------------------------------------------
raw_json = '{"service":"catalog","port":8080}'
parsed_subscript = JSON[raw_json]
assert_instance_of(Hash, parsed_subscript)
assert_equal("catalog", parsed_subscript["service"])
assert_equal(8080, parsed_subscript["port"])

parsed_with_opts = JSON[raw_json, symbolize_names: true]
assert_equal([:service, :port], parsed_with_opts.keys)
assert_equal("catalog", parsed_with_opts[:service])

data_obj = { service: "catalog", port: 8080 }
generated_subscript = JSON[data_obj]
assert_instance_of(String, generated_subscript)
assert_equal('{"service":"catalog","port":8080}', generated_subscript)

via_helper_parse = JsonFeatures.dispatch(raw_json)
assert_equal(parsed_subscript, via_helper_parse)

via_helper_gen = JsonFeatures.dispatch(data_obj)
assert_equal(generated_subscript, via_helper_gen)

# ---------------------------------------------------------------------------
# 2. Arbitrary decimal precision via decimal_class: BigDecimal
# ---------------------------------------------------------------------------
high_precision_json = '{"constant":0.12345678901234567890123456789}'

# Default Float parsing suffers IEEE 754 precision loss
default_parsed = JSON.parse(high_precision_json)
float_val = default_parsed["constant"]
assert_instance_of(Float, float_val)
assert(float_val.to_s != "0.12345678901234567890123456789", "Float was expected to truncate precision")

# Parsing with decimal_class: BigDecimal retains complete precision
exact_parsed = JsonFeatures.parse_exact_decimal(high_precision_json)
dec_val = exact_parsed["constant"]
assert_instance_of(BigDecimal, dec_val)
assert_equal(BigDecimal("0.12345678901234567890123456789"), dec_val)

# ---------------------------------------------------------------------------
# 3. Custom container classes with array_class and object_class
# ---------------------------------------------------------------------------
container_json = '{"nodes":[{"id":1},{"id":2}]}'

custom_result = JsonFeatures.parse_custom_containers(container_json)
assert_instance_of(JsonFeatures::CustomObject, custom_result)
assert_instance_of(JsonFeatures::CustomArray, custom_result["nodes"])
assert_instance_of(JsonFeatures::CustomObject, custom_result["nodes"][0])
assert_equal(1, custom_result["nodes"][0]["id"])

# ---------------------------------------------------------------------------
# 4. JSON.dump IO streaming and recursion depth limit enforcement
# ---------------------------------------------------------------------------
payload = { "host" => "example.com", "metrics" => [10, 20, 30] }
destination_stream = StringIO.new

# Dumping to IO writes to stream and returns the exact IO object
returned_io = JsonFeatures.dump_to_stream(payload, destination_stream)
assert(returned_io.equal?(destination_stream), "JSON.dump should return the destination IO object")
assert_equal('{"host":"example.com","metrics":[10,20,30]}', destination_stream.string)

# Enforcing depth limits via JSON.dump raises ArgumentError on exceed
shallow_limit_err = assert_raises(ArgumentError) do
  JsonFeatures.dump_with_depth_limit([[[[1]]]], 3)
end
assert(shallow_limit_err.message.include?("exceed depth limit"), "Expected depth limit message in ArgumentError")

# Within depth limit, JSON.dump returns formatted string
allowed_depth_str = JsonFeatures.dump_with_depth_limit([[[1]]], 5)
assert_equal("[[[1]]]", allowed_depth_str)

# ---------------------------------------------------------------------------
# 5. Core type additions (Time, Date, Struct, Set, Symbol) bidirectional round-trip
# ---------------------------------------------------------------------------
# Time with nanosecond precision
time_source = Time.utc(2026, 8, 17, 14, 45, 30, 987654)
time_json = time_source.to_json
assert_equal("Time", JSON.parse(time_json)["json_class"])
restored_time = JSON.parse(time_json, create_additions: true)
assert_instance_of(Time, restored_time)
assert_equal(time_source, restored_time)
assert_equal(time_source.nsec, restored_time.nsec)

# Date
date_source = Date.new(2026, 8, 17)
date_json = date_source.to_json
assert_equal("Date", JSON.parse(date_json)["json_class"])
restored_date = JSON.parse(date_json, create_additions: true)
assert_instance_of(Date, restored_date)
assert_equal(date_source, restored_date)

# Struct
Employee = Struct.new("Employee", :id, :title) unless defined?(Employee)
struct_source = Employee.new(42, "lead")
struct_json = struct_source.to_json
assert_equal("Struct::Employee", JSON.parse(struct_json)["json_class"])
restored_struct = JSON.parse(struct_json, create_additions: true)
assert_instance_of(Employee, restored_struct)
assert_equal(struct_source, restored_struct)

# Set containing Symbols
set_source = Set.new([:read, :write])
set_json = set_source.to_json
assert_equal("Set", JSON.parse(set_json)["json_class"])
restored_set = JSON.parse(set_json, create_additions: true)
assert_instance_of(Set, restored_set)
assert_equal(set_source, restored_set)
assert(restored_set.all? { |item| item.is_a?(Symbol) }, "Set elements should remain Symbol instances")

# Without create_additions: true, outputs remain plain Hash representations
plain_hash = JSON.parse(time_json)
assert_instance_of(Hash, plain_hash)
assert_equal("Time", plain_hash["json_class"])

# ---------------------------------------------------------------------------
# 6. JSON.create_id customization
# ---------------------------------------------------------------------------
saved_create_id = JSON.create_id
begin
  # Changing create_id changes which key is recognized as the addition class name
  JSON.create_id = "_class"
  custom_tag_json = '{"_class":"Time","s":1786968000,"n":0}'

  # Standard json_class is ignored when create_id is changed
  ignored_standard = JSON.parse(time_json, create_additions: true)
  assert_instance_of(Hash, ignored_standard)

  # Custom tag is instantiated
  instantiated_custom = JSON.parse(custom_tag_json, create_additions: true)
  assert_instance_of(Time, instantiated_custom)
ensure
  JSON.create_id = saved_create_id
end

puts "Contract passed: all JSON behaviors verified successfully."

오리진 시더

csx-seed