stampit-org / stampit

OOP is better with stamps: Composable object factories.
https://stampit.js.org
MIT License
3.02k stars 102 forks source link

Initializer bug or am i missing something ? #324

Closed MarcLoupias closed 7 years ago

MarcLoupias commented 7 years ago

Hello,

i am playing with codes examples in the Fun with Stamps medium.com articles series.

Just found something strange in the Breaking down a stamp into pieces from the first article code examples :

#!/usr/bin/env node
'use strict';

const {compose, init} = require('stampit');

const HasFoo = compose({
    properties: {
        foo: 'default foo!'
    }
});

const PrintFoo = compose({
    methods: {
        printFoo() {
            console.log(this.foo || 'There is no foo');
        }
    }
});

const InitFoo = init(function(foo) {
    console.log('init arg value is ', foo);
    if (foo) this.foo = foo;
});

const Foo = compose(HasFoo, PrintFoo, InitFoo);

const objNoArg = Foo();
console.log('objNoArg :', objNoArg); // objNoArg : { foo: {} }

const objArgNull = Foo(null);
console.log('objArgNull :', objArgNull); // objArgNull : { foo: 'default foo!' }

When the initializer receive no value at all, the stamp lib replace undefined by an empty literal object, so the if statement is true instead of false, and the default value is overwritten with the literal object.

I am using stampit@3.2.1 and node 6.11.3.

koresar commented 7 years ago

Oh, right. The article was written before this change: https://github.com/stampit-org/stamp-specification/issues/93 Thank you for finding it!

Basically, the first argument is considered an options object. Thus, should never be undefined. You can manually specify null which is an object typeof null === 'object'.

Let me fix the article.

koresar commented 7 years ago

The article should be fixed now.

Thank you for the great issue!

MarcLoupias commented 7 years ago

Oooookayyyyy ;)

It's crystal clear now.

It imply that factory function have to takes an object as param.

We cannot do that const myInstance = FactoryFn(val1, val2 ...)

We have to do that const myInstance = FactoryFn({prop1: 'val1', prop2: 'val2', ...})

To be honest the rtype spec to describe stamps add a step in the library adoption. You want to learn stamp but you have to learn rtype + stamp. Javascript executable examples in addition to the rtype def in the stamp-specification repo would be valuable.

Thanks !

EDIT : In fact it is obvious when thinking about it. Should be really obvious for seasoned functional programming developpers which is not my case, everything is new to me.