Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add replacer code similar to JSON replacer and (configurable) toJSON #392

Closed
wants to merge 1 commit into from

Conversation

sjpt
Copy link

@sjpt sjpt commented Jan 23, 2018

I apologize if I haven't created this request correctly; still very unused to git.
I have changed the base file lib/js-yaml/dumper,js, but not built any dist/js-yaml.js or similar files.
Also, there are just two test cases which are for the moment included inline in dumper.js.

Copy link

@graphicore graphicore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing this, it's a good starting point. I think though, if we do this, we need to take serious care about the details. There is a specification for this, it's in the ECMAScript standartd for JSON.stringify

jjj = JSON.stringify(obj, repl)
console.log('yyy => ', yyy); console.log('jjj => ', jjj)
***/
let object = oobject; // keep original for debug

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if let is good to use in js-yaml. If the code should be compatible with older browsers, var would be preferable. Having a look at dumper.js, var is definitely the thing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

about // keep original for debug, I wouldn't recommend that as a motive, you can still assign oobject to a value in the debugger if you want to keep it around. However, as pointed out before, chrome optimizes better when function parameters are not overridden.

This line should be:

var object_ = object;

@@ -682,7 +684,31 @@ function detectType(state, object, explicit) {
// Serializes `object` and writes it to global `result`.
// Returns true on success, or false on invalid object.
//
function writeNode(state, level, object, block, compact, iskey) {
function writeNode(state, level, oobject, block, compact, iskey) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have to change the signature. use object instead of oobejct. oobject reads badly in documentation.

Rather use later:

var object_ = object;

Also, because overwriting values of function parameters has a bad influence on chrome (the browser) performance optimization behavior.

function writeNode(state, level, object, block, compact, iskey) {
function writeNode(state, level, oobject, block, compact, iskey) {
// replacement, sjpt
/** test case:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a proper test-suite, we should have tests there.

console.log('yyy => ', yyy); console.log('jjj => ', jjj)
***/
let object = oobject; // keep original for debug
if (typeof object === 'object' && object[state.localReplacer]) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add

&& typeof object[state.localReplacer] === 'function'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This:

&& object[state.localReplacer]

must be rather:

&& Object.prototype.hasOwnProperty.call(object, state.localReplacer)

***/
let object = oobject; // keep original for debug
if (typeof object === 'object' && object[state.localReplacer]) {
object = object[state.localReplacer].apply(object);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not called correctly:

JSON.stringify() calls toJSON with one parameter:

  • if this object is a property value, the property name
  • if it is in an array, the index in the array, as a string
  • an empty string if JSON.stringify() was directly called on this object

do it like this:

object_ = object[state.localReplacer](key || '');

NOTE: we have a problem here, writeNode is not aware of the key it is writing.

Also, not each invocation of writeNode writes a value, some invocations just write keys, see the isKey parameter. If isKey is true, we should never even consider calling any replacer.

if (typeof object === 'object' && object[state.localReplacer]) {
object = object[state.localReplacer].apply(object);
}
if (state.replacer) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@graphicore graphicore mentioned this pull request Jan 24, 2018
@rlidwka
Copy link
Member

rlidwka commented Dec 22, 2020

implemented slightly differently in 359b264

@rlidwka rlidwka closed this Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants