Jump to content

Private vars in Coffeescript


alex_h
 Share

Recommended Posts

A question for any coffeescript users:

 

We're using coffeescript on a fairly large Cocos2D based project at my work. We're looking at options for which pattern of inheritance to use for our code base. Cocos2D uses a John Resig style system, but this doesn't seem to provide any means of having private instance methods or variables. My personal vote goes for the straightforward inheritance system used in Pixijs like this:

ClassA = function(){  var privateNum = 5//<-- this variable is 'private'}ClassB = function(){   ClassA.call(this)   //I can't access the private value from here}ClassB.prototype = Object.create(ClassA.prototype)

But some coffeescript enthusiasts amongst my colleagues feel they might prefer the built in coffeescript system of defining classes using the coffeescript keyword 'class'

 

class ClassA  constructor:() ->   cc.log "new ClassA constructed"    return  publicMethod:()->    #this does get inherited    cc.log "publicMethod was called"    return  privateMethod = ()->    #this does NOT get inherited    return  publicVar:2  privateVar = 3 #this doesn't behave as required, the value is shared between instancesclass ClassB extends ClassA  constructor:() ->    super    cc.log "new ClassB constructed"    return

I've done a bit of testing and discovered that if I define methods of my classes using the equals sign rather than a colon then they are compiled as private functions rather than class members, which is great. The same seemed to go for variables too, but then it turned out that due to the way coffeescript compiles its classes into javascript the values of these variables gets shared between class instances. So they are not really instance variables, they are actually variables defined on the class itself, a bit like static variables in AS3.

 

Is there anybody out there who is more familiar with coffeescript and can let me know if there is a real way to do 'private' vars in coffeescript classes.

To attempt to clarify a bit what I mean by private, I mean a variable defined within the scope of the closure that makes up the class, but not defined as a property of 'this'.

var MyClassDefinition = function(){   var foo = 1;//<-- this is private because you can't get at it from outside the class scope/closure   this.bar = 2;//this is not private, you can access it from outside}var myInstance = new MyClassDefinition()var fetchNum = myInstance.bar;//<-- I can access the bar variable as an instance property, but not the foo.

Just to pre-empt any clever-dick replies, no, stopping using coffeescript is not a possible solution to this question.

It's not up to me to make this decision anyway.

;)

 

 

 

 

 

 

Link to comment
Share on other sites

Sorry for being a clever-dick, but this is why I don't like Coffescript. It try to emulate things, that were not designed to be in JS in first place, for various of reasons. It's like buying Mac and installing Windows on it.

You will run in such problems a lot of times. 

 

But in order to help you: http://stackoverflow.com/questions/9886761/coffeescript-private-class-instance-variables

 

You can have "private" variables using scopes, but not using CS class system. If you will just make a factory function (like you should do), that returns object you want, then in this factory you can define var and it will be private and not shared among all instances. Because every call to factory creates new scope. By Using CS class system you call function creating private var only once so all instances share that var.

 

And take into account, that you can't make protected variable (private that can be inherited), but using closure you can make setter and getter for it, so childs can edit it.

 

EDIT: One more thing. Ask guys in your company, why you need private variables in first place? Because, IMHO, private variables are used to make code idiot proof, which results in easier debugging process. If you won't use private, then it "might" happen that one of programmers will edit variable that shouldn't not be edited from outside of object, and thus that would cause a bug harder to find. But if your code is well designed, modularized, then this should not happen. More about that here: http://programmers.stackexchange.com/questions/143736/why-do-we-need-private-variables

If you are writing API for outside clients, then privates are a good thing, because clients often don't read documentation and they access/edit variables they should not. So later when you release update to your API, their code breaks.

Link to comment
Share on other sites

Thanks for the reply, I agree that there are definitely pros and cons to using coffeescript. That stack overflow page has some typically irritating comments in it though doesn't it! Delivered in the obligatory arrogant / smug tone of course ;)

 

Like this one for instance:

 

Now ask yourself: what is so hurtful in having all members puplic? 

 

Well if there was no benefit to having private members then why the f&@k would so many languages make use of them? What a stupid comment!

I am working as part of a team of 10 or so developers and I want to provide them with code with a fixed API that is accessible to them. However my classes will also include functionality that I want to be 'hidden' or inaccessible, so that when testing and debugging this will help me track down the source of a given problem. For example I can be sure that the problem hasn't come from my colleague passing the wrong value to some function or other because that function is set as private precisely so that it can't be messed with.

 

Anyway so your answer is:

You can have "private" variables using scopes, but not using CS class system

Fine, that is what I thought. We are now considering making our own modified version of the coffeescript compiler that will compile classes 'properly', ie as a simple closure so that you can treat local variables within that scope as private.

Link to comment
Share on other sites

if your code is well designed, modularized, then this should not happen. 

 

Yeah it should not, but it still might. It definitely makes life easier if you can be 100% sure that some parts of the code are inaccessible. Also, it makes somebody elses code much quicker and easier to learn to use if you know you only have to focus on those parts of it that are public. The private sections you know you can ignore, they will just do what they are supposed to do, you can just concentrate on learning how to use the public API. Otherwise you can be faced with pages and pages of code, all of which is declared public and you don't have any way of knowing which bits are relevant to you other than either wasting time reading through all of it, or wasting somebody elses time by asking them to explain it to you.

Link to comment
Share on other sites

Yeah it should not, but it still might. It definitely makes life easier if you can be 100% sure that some parts of the code are inaccessible. Also, it makes somebody elses code much quicker and easier to learn to use if you know you only have to focus on those parts of it that are public. The private sections you know you can ignore, they will just do what they are supposed to do, you can just concentrate on learning how to use the public API. Otherwise you can be faced with pages and pages of code, all of which is declared public and you don't have any way of knowing which bits are relevant to you other than either wasting time reading through all of it, or wasting somebody elses time by asking them to explain it to you.

well, you should create a "facade" and document it. Searching through all source code is always a waste of time, even if someone uses privates. But I'm not saying that privates are useless. It's just not worth IMO to create new coffeescript compilation just to add privates support.

Link to comment
Share on other sites

well, you should create a "facade" and document it. 

maybe, but it's kind of annoying that I have to do this extra work just because coffeescript isn't set up to let me work the way I would like to.

 

It's just not worth IMO to create new coffeescript compilation just to add privates support.

 

Yeah, I'd agree it is a bit of an extreme reaction to the problem. One of my colleagues suggested it as a possible solution, could be an interesting investigation though at any rate.

Link to comment
Share on other sites

  • 3 weeks later...

My colleague just found this info which explains that you can have private instance vars in coffeescript after all, they just need to be defined within the class constructor, which kind of makes sense when i think about how I would achieve private instance vars in plain js

 

 

in your class definition:

@nose: or @nose = defines a static (class) variable/function
nose: defines a prototype variable/function
nose= defines a private variable/function

in your constructor:
nose= defines a private variable for an instance of the class
@nose= defines an ‘instance’ variable for an instance of the class

 

 

http://www.cs8.my/2012/09/coffeescript-classes-and-their-variables/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...