Re: [apps-discuss] draft-snell-merge-patch-08 in Ruby

"Manger, James H" <James.H.Manger@team.telstra.com> Mon, 20 May 2013 23:50 UTC

Return-Path: <James.H.Manger@team.telstra.com>
X-Original-To: apps-discuss@ietfa.amsl.com
Delivered-To: apps-discuss@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 4A14721F8E4E for <apps-discuss@ietfa.amsl.com>; Mon, 20 May 2013 16:50:12 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 0.949
X-Spam-Level:
X-Spam-Status: No, score=0.949 tagged_above=-999 required=5 tests=[AWL=-1.050, BAYES_00=-2.599, HELO_EQ_AU=0.377, HOST_EQ_AU=0.327, J_CHICKENPOX_54=0.6, MANGLED_FORM=2.3, RELAY_IS_203=0.994]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xIB9cJtEO90f for <apps-discuss@ietfa.amsl.com>; Mon, 20 May 2013 16:50:05 -0700 (PDT)
Received: from ipxbvo.tcif.telstra.com.au (ipxbvo.tcif.telstra.com.au [203.35.135.204]) by ietfa.amsl.com (Postfix) with ESMTP id 3D39921F90DF for <apps-discuss@ietf.org>; Mon, 20 May 2013 16:50:04 -0700 (PDT)
X-IronPort-AV: E=Sophos;i="4.87,711,1363093200"; d="scan'208";a="136688059"
Received: from unknown (HELO ipccvi.tcif.telstra.com.au) ([10.97.217.208]) by ipobvi.tcif.telstra.com.au with ESMTP; 21 May 2013 09:50:04 +1000
X-IronPort-AV: E=McAfee;i="5400,1158,7081"; a="133216444"
Received: from wsmsg3705.srv.dir.telstra.com ([172.49.40.203]) by ipccvi.tcif.telstra.com.au with ESMTP; 21 May 2013 09:50:04 +1000
Received: from WSMSG3153V.srv.dir.telstra.com ([172.49.40.159]) by WSMSG3705.srv.dir.telstra.com ([172.49.40.203]) with mapi; Tue, 21 May 2013 09:50:03 +1000
From: "Manger, James H" <James.H.Manger@team.telstra.com>
To: James M Snell <jasnell@gmail.com>, Steve Klabnik <steve@steveklabnik.com>, "apps-discuss@ietf.org" <apps-discuss@ietf.org>
Date: Tue, 21 May 2013 09:50:02 +1000
Thread-Topic: [apps-discuss] draft-snell-merge-patch-08 in Ruby
Thread-Index: Ac5VeHk6OsL5Pkx9R22mvwEgQVGKhgAON8zg
Message-ID: <255B9BB34FB7D647A506DC292726F6E1151A56EEE3@WSMSG3153V.srv.dir.telstra.com>
References: <CABL+ZB6AQGp8WUeH=HZrfm4VCQnmYFQB5vBGP0yghAZUhsjCQg@mail.gmail.com> <255B9BB34FB7D647A506DC292726F6E1151A34C59E@WSMSG3153V.srv.dir.telstra.com> <CABL+ZB6tkggqrdjPFz38j=AXGuueSbANzER24Njm-o3a2S=MZA@mail.gmail.com> <255B9BB34FB7D647A506DC292726F6E1151A56E41B@WSMSG3153V.srv.dir.telstra.com> <CABL+ZB6=X9vTwDZ9ORPWm9u7PNSaaisLvenSRifmjsO6BCOuxA@mail.gmail.com> <CABP7Rbc7VxOG3Y7zapNQ2oW=yO9=PitACzRLntzXXnQ1dj+04A@mail.gmail.com>
In-Reply-To: <CABP7Rbc7VxOG3Y7zapNQ2oW=yO9=PitACzRLntzXXnQ1dj+04A@mail.gmail.com>
Accept-Language: en-US, en-AU
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
acceptlanguage: en-US, en-AU
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.0
Subject: Re: [apps-discuss] draft-snell-merge-patch-08 in Ruby
X-BeenThere: apps-discuss@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: General discussion of application-layer protocols <apps-discuss.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/apps-discuss>, <mailto:apps-discuss-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/apps-discuss>
List-Post: <mailto:apps-discuss@ietf.org>
List-Help: <mailto:apps-discuss-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/apps-discuss>, <mailto:apps-discuss-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 20 May 2013 23:50:13 -0000

> Given James M's example cases, the results should be:
> 
> > Document + patch = ?
> 
> > [1,2]  +  {"a":"foo","b":null}
> 
>   Result: {"a":"foo"}

The JavaScript in draft-snell-merge-patch-08 incorrectly gives the result as [1,2].


> > {"a":"foo"}  +  {"b":[3,null,{"x":null}]}
> 
>   Result: {"a":"foo", "b":[3,{}]}

NO. The result should be: {"a":"foo", "b":[3,null,{"x":null}]}.
Merge-patch does NOT merge arrays; it treats them like other primitives (strings, numbers, booleans) so a merge-patch implementation should NOT be looking inside an array for nulls.

The JavaScript in draft-snell-merge-patch-08 gives neither of these results. It incorrectly gives {"a":"foo", "b":[3,{"x":null}]}


> > {"a":"foo"}  +  null
> 
>   Result: Invalid. The patch document MUST be a valid JSON document,
> which means the root must be either a JSON object or array. A null
> patch document is invalid.

I thought the one non-controversial change planned for RFC4627 "JSON" was to allow any JSON value (not just arrays and objects) as a JSON-text.

A patch of null certainly should not return the original unchanged (as the JavaScript in draft-snell-merge-patch-08 does). Either throw an error, or return an undefined value.


> If there is an error in the javascript impl in the draft, I'll make
> sure that gets corrected in the next iteration.

My suggested JavaScript implementation:

function merge(orig, patch) {
	var result;
	if (patch === null) {
		// leave result undefined
	}
	else if (typeof patch === 'string' ||
		typeof patch === 'number' ||
		typeof patch === 'boolean' ||
		Array.isArray(patch))
	{
		result = patch;
	}
	else { // patch is an object
		result = {};
		if (orig instanceof Object && !Array.isArray(orig)) {
			for (m in orig)
				result[m] = orig[m];
		}
		for (m in patch) {
			result[m] = merge(result[m], patch[m]);
		}
	}
	return result;
}

See it in action at http://id.cto.telstra.com/json/merge.html

--
James Manger