Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Records and methods #384

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

Closed
AlgoTrader opened this issue Mar 11, 2015 · 7 comments
Closed

Records and methods #384

AlgoTrader opened this issue Mar 11, 2015 · 7 comments

Comments

@AlgoTrader
Copy link

It seems, Records are of great interest and it is one of killer features of Immutable.js. I start to use it, but unfortunately ES6 is not yet there for extending Records with methods and ES5 inheritance is pain.

For now, I "embed" methods into Records like this:

var Complex = Immutable.Record({real:0, image:0, magnitude:function() { return Math.sqrt(this.real*this.real+this.image*this.image);}});

var num = new Complex({real:1, image:2})

num.magnitude()
2.23606797749979

In reality, there is for example isNull method that shows the record has no real value. It would be useful to allow prototype extending in Record constructor, not sure it is acceptable for functional programming purists though.

I also heavily support the idea of making Records efficient (#286). Records can be lightweight structures, they are often used for small "value" types and they never change keys

@kentor
Copy link

kentor commented Mar 13, 2015

I do this for adding methods to record instances:

var Person = Immutable.Record({ name: '' });
Person.prototype.sayHi = function() {
  return this.name;
});

@copy
Copy link

copy commented Mar 14, 2015

For now, you can also get an efficient structure and methods by defining your own objects with equals and hashCode like so:

function Complex(p)
{
    this.real = p.real;
    this.image = p.image;
}

Complex.prototype.equals = function(other)
{
    return this.real === other.real && this.image === other.image;
};

Complex.prototype.hashCode = function()
{
    return util.hash_int32array([
        this.real,
        this.image,
    ]);
};

Complex.prototype.magnitude = function()
{
    return Math.sqrt(this.real*this.real + this.image*this.image);
};

@leebyron
Copy link
Collaborator

@copy, I'm glad you've caught onto this pattern! I haven't documented it anywhere yet, but in the next major version, I will document this as a way to define "value" objects that work in the Immutable.js ecosystem (eg, can be used as keys, and are considered values by Immutable.is())

@leebyron
Copy link
Collaborator

Methods can be added to Record classes as @kentor describes. Simply add methods to the prototype. It is probably not a good idea to add them as values in the Record.

Some ES6 transpilers support extending expressions, in which case you can write:

class Complex extends Record({real:1, image:1}) {
magnitude() { return ...; }
}

For the transpilers that don't support subclassing an expression, but support an identifier, you can write:

var _Complex = Record({...})
class Complex extends _Complex {
...
}

I personally prefer just adding methods to the prototype.

@mschipperheyn
Copy link

So, we can add hashCode and equals like @copy describes using the way @kentor describes? This would basically work using an immutable Set to guarantee unique Record based object in the Set?

@turnerhayes
Copy link

Can we return altered versions of records from Record methods? I have the following:

class MyRecord extends Record({...}) {
    updateIssues = (issues) => this.mergeDeepIn(["items"], Map(issues.map(issue => [issue.id, issue])));
}

as a method of a Record class, and when I call it, I get back something that the debugger claims is an instance of MyRecord, but there is no updateIssues() method on it anymore.

@semireg
Copy link

semireg commented Oct 1, 2019

@turnerhayes

I found that declaring methods as properties like that, it works OK within the same file. But the methods do not appear when accessed outside this file.

I had luck rewriting as actual methods:

class MyRecord extends Record({...}) {
    updateIssues(issues) {
        return this.mergeDeepIn(["items"], Map(issues.map(issue => [issue.id, issue])));
    }
}

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

No branches or pull requests

7 participants