-
Notifications
You must be signed in to change notification settings - Fork 113
What about protected fields? #86
Comments
The quotes around "protected" are accurate; in your usage, it's fully public - can you elaborate on how you think we could specify "protected" such that subclasses defined in separate modules/files could have access to the fields, but everyone else would be fully denied access? |
See previously and also the rest of that thread, which has some links to other previous discussions. |
If you mean how to implement it in the engine, I'm not sure about that, I'm not familiar with engine implementation much (barely). If you mean, how to symbolize it syntactically, I'm sure we can come up with something. F.e. The "protected" concept of my JS version in lowclass "accessible only to the class and its subclasses" (as mentioned where you linked @bakkot) but external code can not access the properties (similar to C++/Ruby I suppose, which I think I like most so far, and I think C++ is a good reference point in general). With private properties in lowclass, "a property is only accessible by the class" as mentioned in that other thread too. For example, try this: npm i lowclass const Class = require('lowclass')
const Foo = Class((public, protected, private) => ({
foo() {
console.log('foo is public')
},
protected: {
bar() {
console.log('bar is protected')
},
},
private: {
baz() {
console.log('baz is private')
},
},
}))
// (alternate "syntax" here, defining props/methods on helpers instead of returning an object)
const Bar = Foo.subclass((public, protected, private, _super) => {
public.test = function() {
this.foo()
// call super protected method from public method
_super(protected(this)).bar()
try { _super(private(this)).baz() }
catch(e) { console.log('unable to access privates, 1') }
try { this.baz() }
catch(e) { console.log('unable to access privates, 2') }
protected(this).test2()
}
protected.test2 = function() {
console.log('call inherited protected member from protected')
// try various ways:
this.bar()
_super(this).bar() // redundant
_super(protected(this)).bar() // even more reduntant
private(this).test3()
}
private.test3 = function() {
console.log('call inherited protected member from private')
// try various ways:
try { this.bar() } // error
catch(e) { console.log('bar is not private of this class') }
try { _super(this).bar() } // error
catch(e) { console.log('privates are not currently inheritable (we could change that)') }
_super(protected(this)).bar() // works
}
})
const f = new Foo
f.foo()
// not possible to access privates in outside code
try { f.baz() }
catch(e) { console.log('unable to access privates, 3') }
// not possible to access protecteds in outside code
try { f.bar() }
catch(e) { console.log('unable to access protected, 4') }
const b = new Bar
b.test() Output:
Personally I like the expressiveness of the words |
Sidenote, it is possible to leak the access helpers, which usually should be avoided, but it might be useful in cases where the data is still private to a module file, and only the public API is exported (this is the nice thing about the runtime implementation): let parentPrivate
const Parent = Class((public, protected, private) => {
parentPrivate = private
private.foo = 'i am private'
})
const Child = Parent.subclass(() => ({
constructor() {
const parent = new Parent
console.log( parentPrivate(parent).foo ) // => i am private
},
}))
export { Parent, Child } import { Child } from '...'
new Child // => i am private There could be some interesting use cases for this, sort of like "module private" of sorts, etc. Not possible with only the syntax in this proposal, but possible with runtime because it's all just references. |
The majority of the time, when I write something like
this._foo = 'bar'
, it ends up being a "protected" member when subclasses refer to the property yet I don't want the property to be part of the public API. A good chunk of the time the properties remain "private".It would be great if this proposal would have all three of public, protected, and private fields.
Here's an class utility I made with public, protected, and private members, including a super helper for super public or protected methods (I can support super for private methods too, but I wasn't sure yet if that makes sense): https://github.com/trusktr/lowclass.
I'm thinking it would interesting to make a Babel plugin that can convert syntax from this proposal into something that uses lowclass at runtime, for proof of concept.
The text was updated successfully, but these errors were encountered: