From 6962f0e2ab68add5e174b7a62fecab4e0138f0dc Mon Sep 17 00:00:00 2001 From: kate Date: Sun, 6 Sep 2026 22:16:21 +0200 Subject: [PATCH 1/2] Fix Array.wrap monkeypatch. --- CHANGELOG.md | 32 +++++++++++++++++++++++ lib/json_logic.rb | 1 - lib/json_logic/engine.rb | 7 ++++- lib/json_logic/ext/array.rb | 5 ---- lib/json_logic/operations/exists.rb | 2 +- lib/json_logic/operations/missing.rb | 2 +- lib/json_logic/operations/missing_some.rb | 2 +- lib/json_logic/operations/try.rb | 2 +- lib/json_logic/semantics.rb | 6 +++++ lib/json_logic/version.rb | 2 +- 10 files changed, 49 insertions(+), 12 deletions(-) delete mode 100644 lib/json_logic/ext/array.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f4830..61bdc24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,38 @@ All notable changes to this project will be documented in this file. +## [0.3.0] - 2026-09-06 +### Fixed +- Fix `Array.wrap` monkeypatch ([#21](https://github.com/tavrelkate/json-logic-rb/issues/21)). + Before, requiring this gem defined `Array.wrap` globally on the core `Array` class. + Had conflict with ActiveSupport's with different `nil` handling (`[]` vs `[nil]`). Whichever loaded last silently won. + +```ruby +require "json-logic-rb" + +Array.respond_to?(:wrap) +# <= 0.2.0 => true +``` + + Now the gem no longer touches `Array` globally. JsonLogic still wrap a single raw value into a array without dropping any elements (specially `nil`), but that rule now lives inside internal `JsonLogic::Semantics` instead of on core `Array`. + +```ruby +require "json-logic-rb" + +Array.respond_to?(:wrap) +# 0.3.0 => false +``` + + ActiveSupport's own `Array.wrap` is no longer shadowed: + +```ruby +require "active_support/core_ext/array/wrap" +require "json-logic-rb" + +Array.wrap(nil) +# 0.3.0 => [] (ActiveSupport's behavior) +``` + ## [0.2.0] - 2026-02-17 ### Added - Add community-extra operators: `try`, `throw`, `exists`, `val`, and `??` (`coalesce`). diff --git a/lib/json_logic.rb b/lib/json_logic.rb index 7de5623..c452cc2 100644 --- a/lib/json_logic.rb +++ b/lib/json_logic.rb @@ -6,7 +6,6 @@ require_relative 'json_logic/errors/logic_error' require_relative 'json_logic/errors/invalid_arguments_error' require_relative 'json_logic/errors/nan_error' -require_relative 'json_logic/ext/array' require_relative 'json_logic/tree' require_relative 'json_logic/scope' require_relative 'json_logic/operation' diff --git a/lib/json_logic/engine.rb b/lib/json_logic/engine.rb index 717b371..d34dc63 100644 --- a/lib/json_logic/engine.rb +++ b/lib/json_logic/engine.rb @@ -33,7 +33,12 @@ def evaluate(rule, data = nil) return rule.transform_values { |value| evaluate(value, data) } end - args = op_class.values_only? ? Array.wrap(evaluate(raw_args, data)) : raw_args + if op_class.values_only? + evaluated = evaluate(raw_args, data) + args = evaluated.is_a?(Array) ? evaluated : [evaluated] + else + args = raw_args + end begin result = op_class.new.call(args, data) raise JsonLogic::NaNError.new if result.is_a?(Float) && (result.nan? || result.infinite?) diff --git a/lib/json_logic/ext/array.rb b/lib/json_logic/ext/array.rb deleted file mode 100644 index ea7bf33..0000000 --- a/lib/json_logic/ext/array.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class Array - def self.wrap(value) = value.is_a?(Array) ? value : [value] -end diff --git a/lib/json_logic/operations/exists.rb b/lib/json_logic/operations/exists.rb index 42b80bc..53a42b3 100644 --- a/lib/json_logic/operations/exists.rb +++ b/lib/json_logic/operations/exists.rb @@ -10,5 +10,5 @@ def call(args, data) = JsonLogic::Tree.new(data).exists?(normalize_path(args, da private - def normalize_path(args, data) = args.is_a?(Array) ? Array.wrap(args).map { |part| JsonLogic.apply(part, data) } : JsonLogic.apply(args, data) + def normalize_path(args, data) = args.is_a?(Array) ? args.as_array.map { |part| JsonLogic.apply(part, data) } : JsonLogic.apply(args, data) end diff --git a/lib/json_logic/operations/missing.rb b/lib/json_logic/operations/missing.rb index 128aba6..d8a8281 100644 --- a/lib/json_logic/operations/missing.rb +++ b/lib/json_logic/operations/missing.rb @@ -6,6 +6,6 @@ class JsonLogic::Operations::Missing < JsonLogic::Operation def self.name = "missing" def call(args, data) - Array.wrap(args).select { |key| JsonLogic::Tree.new(data).dig(key).nil? } + args.as_array.select { |key| JsonLogic::Tree.new(data).dig(key).nil? } end end diff --git a/lib/json_logic/operations/missing_some.rb b/lib/json_logic/operations/missing_some.rb index 4963d1b..cbd81db 100644 --- a/lib/json_logic/operations/missing_some.rb +++ b/lib/json_logic/operations/missing_some.rb @@ -7,7 +7,7 @@ def self.name = "missing_some" def call((min_ok, list), data) json = JsonLogic::Tree.new(data) - keys = Array.wrap(list) + keys = list.as_array missing = keys.select { |key| json.dig(key).nil? } (keys.size - missing.size) >= min_ok ? [] : missing end diff --git a/lib/json_logic/operations/try.rb b/lib/json_logic/operations/try.rb index f06d0dd..75aa607 100644 --- a/lib/json_logic/operations/try.rb +++ b/lib/json_logic/operations/try.rb @@ -6,7 +6,7 @@ class JsonLogic::Operations::Try < JsonLogic::LazyOperation def self.name = "try" def call(arguments, data) - arguments = Array.wrap(arguments) + arguments = arguments.as_array raise JsonLogic::InvalidArgumentsError.new if arguments.empty? state = { data: data, error: nil } diff --git a/lib/json_logic/semantics.rb b/lib/json_logic/semantics.rb index fa4c072..09bb23f 100644 --- a/lib/json_logic/semantics.rb +++ b/lib/json_logic/semantics.rb @@ -84,6 +84,12 @@ def !@ def to_bool JsonLogic::Semantics.truthy?(self) end + + def as_array = [self] + end + + refine Array do + def as_array = self end [String, Integer, Float, NilClass, Array, TrueClass, FalseClass].each do |klass| diff --git a/lib/json_logic/version.rb b/lib/json_logic/version.rb index 3ccc999..b4ffecd 100644 --- a/lib/json_logic/version.rb +++ b/lib/json_logic/version.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -module JsonLogic; VERSION = '0.2.0'; end +module JsonLogic; VERSION = '0.3.0'; end From 3cb6e90a4c1fc68ec7b1cac3fe2d843644261899 Mon Sep 17 00:00:00 2001 From: kate Date: Sun, 6 Sep 2026 22:40:01 +0200 Subject: [PATCH 2/2] Update require path in the examples. --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61bdc24..3264db4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file. Had conflict with ActiveSupport's with different `nil` handling (`[]` vs `[nil]`). Whichever loaded last silently won. ```ruby -require "json-logic-rb" +require 'json_logic' Array.respond_to?(:wrap) # <= 0.2.0 => true @@ -18,7 +18,7 @@ Array.respond_to?(:wrap) Now the gem no longer touches `Array` globally. JsonLogic still wrap a single raw value into a array without dropping any elements (specially `nil`), but that rule now lives inside internal `JsonLogic::Semantics` instead of on core `Array`. ```ruby -require "json-logic-rb" +require 'json_logic' Array.respond_to?(:wrap) # 0.3.0 => false @@ -28,7 +28,7 @@ Array.respond_to?(:wrap) ```ruby require "active_support/core_ext/array/wrap" -require "json-logic-rb" +require 'json_logic' Array.wrap(nil) # 0.3.0 => [] (ActiveSupport's behavior)