Hi,
Following recent discussions about the way you should be away to access other classes private variables and methods, I've written a draft about a new proposed feature called "Access Control" : http://haxe.org/manual/acl Thank you for your feedback, especially about the naming choice of @:give/@:access which I'm not 100% happy with, but it's not very easy to find better (please prove me wrong). Best, Nicolas -- haXe - an open source web programming language http://haxe.org |
@:give and @:take? It also happens to be an English idiom.
On Sun, Nov 6, 2011 at 9:59 AM, Nicolas Cannasse <[hidden email]> wrote: Hi, -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
C++ (for one) uses "friend" to give access
I don't mind, @:give though Not sure about @:access - why not @:take My 2 cents John On 6 November 2011 19:59, Nicolas Cannasse <[hidden email]> wrote: Hi, -- haXe - an open source web programming language http://haxe.org |
In reply to this post by laurence taylor
Le 06/11/2011 10:10, Laurence Taylor a écrit :
> @:give and @:take? It also happens to be an English idiom. "giving access" seems natural to me but "taking access" seems a bit od. I'm not a native speaker. Best, Nicolas -- haXe - an open source web programming language http://haxe.org |
Hi,
This is a great feature, that was really needed for us engine writers that want to write fast and simple architecture without that crappy friendship/interfaces bloat. Thanks a lot, David. Le dimanche 6 novembre 2011, Nicolas Cannasse <[hidden email]> a écrit : > Le 06/11/2011 10:10, Laurence Taylor a écrit : >> >> @:give and @:take? It also happens to be an English idiom. > > "giving access" seems natural to me but "taking access" seems a bit od. I'm not a native speaker. > > Best, > Nicolas > > -- > haXe - an open source web programming language > http://haxe.org > -- David Elahee -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
Hi,
I do not agree with the proposed features nor do I find them any useful. Accessing private fields as in the way of C++'s "friend" keyword is dangerous and lazy programming that's never really needed, because better patterns are available, such as the Factory in this case. class A { // Private constructor function new() { } // External interfaces visible to the user function doXWithA() { }
} // Internal representation of A // private class AInternal { public var foo_boo; public function new() { }
public function internalOp() {} } // Publically available factory for A // class Factory { public static function create(): A {
return new AInternal(); } } No need of additional magic as it's just confusing for both reviewers and coders. Cheers, Mihail
On Sun, Nov 6, 2011 at 9:59 AM, Nicolas Cannasse <[hidden email]> wrote: Hi, -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
if I import the class I would expect not to put a full qualified class
path. If two classes could be possible I would want it to infer the correct type. for example with the adding keyboard listeners from awhile back I had two classes that I could 'using' one for Int, and one for Strings( letters ) that I could get to easily wire up the key stroke events. If these were private static functions... I would want the function that I had given access to, to be able to infer the correct type even though this is being setup by a macro... this is why I wonder if macro is possible/suitable or if this needs to be deeper in haXe? I think 'access' is not ideal since we talk about giving access or having access, the concept of taking access seems like freedom of information act in the uk so maybe free would work, but 'take' does not sound good. For clarity I suggest a few alternatives appended with Access. @:giveAccess( SecretService ) @:freeAccess( Secrets ) @:giveAccess( SecretService) @:permitAccess(Secrets ) @:giveAccess( SecretService) @:haveAccess( Secrets ) I think maybe the more verbose style I suggest, will make it easier for new users? Or maybe a system where you can setup the access type from a single macro @:Access( SecretService, Give ); @:Access( Secret, Have ); @:Access( Secrets, TwoWay ); @:Access( SecretService, OUT ); @:Access( Secret, IN ); @:Access( Secrets, BOTH ); On 6 Nov 2011, at 08:59, Nicolas Cannasse wrote: > Hi, > > Following recent discussions about the way you should be away to > access other classes private variables and methods, I've written a > draft about a new proposed feature called "Access Control" : > > http://haxe.org/manual/acl > > Thank you for your feedback, especially about the naming choice of > @:give/@:access which I'm not 100% happy with, but it's not very > easy to find better (please prove me wrong). > > Best, > Nicolas > > -- > haXe - an open source web programming language > http://haxe.org -- haXe - an open source web programming language http://haxe.org |
Mikael, I don't understand why friend class concept being lazy and dangerous (maybe you can enlighten me), neither why factory are better patterns, and last I don't even understand how your example work.
Friend class is an easy concept to grasp.
I'm no monster programmer, but keeping thing simple are IMO the best way to maintain your code. btw +1 for the friend keyword since it really looks like it behaves like the cpp friend concept. Ben On Sun, Nov 6, 2011 at 11:42 AM, [hidden email] <[hidden email]> wrote: if I import the class I would expect not to put a full qualified class path. If two classes could be possible I would want it to infer the correct type. -- haXe - an open source web programming language http://haxe.org |
Also it's nice to be able to give friendship to a whole package :D
Ben
-- haXe - an open source web programming language http://haxe.org |
In reply to this post by bubblebenj
Friend class concept violates basic principles of OO design and encapsulation. Clearly, a private variable is part of the internal state of an object and no other object should access that. When you use friendly classes you say "I have a private var which is not really private, because someone else than I has access" which is in effect an oxymoron. 99,99% of the cases you use friendly variables you have a very bad and wrong design of in your architecture. Almost all cases of apparatent friendship relations are solved by giving the user an external interface / class:
interface IInterface { function allowedOperation(); } implementing that interface privately so that other internal code can communicate with your internal representation (your "relationship"):
class InternalRepresentation implements IInterface { function someFunctionThatInternalCodeCanCallInsteadOfFriendlyFields() { } } and you return InternalRepresentation to the outside world. Do not ruin good design for simplicity, ever. Regards, Mihail On Sun, Nov 6, 2011 at 1:13 PM, benjamin Dubois <[hidden email]> wrote: Mikael, I don't understand why friend class concept being lazy and dangerous (maybe you can enlighten me), neither why factory are better patterns, and last I don't even understand how your example work. -- haXe - an open source web programming language http://haxe.org |
I still don't get how you restrict access with interface.
OK you don't have access to the private field, but the problem is only transferred to implementation of the interface (not sure I'm clear).
You may still want to be capable to : always restrict access except for few classes. The first thing I have I mind is the implementation of a Renderer. You want it to be capable to access some RenderableObjects fields or functions that could not be accessed by other classes except the renderer.
Thus what was under the hood is kept under the hood. Hey I may be wrong, and it may be done with an interface (?) (Really I'd be happy to learn).
Ben
On Sun, Nov 6, 2011 at 2:04 PM, Mihail Ivanchev <[hidden email]> wrote: Friend class concept violates basic principles of OO design and encapsulation. Clearly, a private variable is part of the internal state of an object and no other object should access that. When you use friendly classes you say "I have a private var which is not really private, because someone else than I has access" which is in effect an oxymoron. 99,99% of the cases you use friendly variables you have a very bad and wrong design of in your architecture. Almost all cases of apparatent friendship relations are solved by giving the user an external interface / class: -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Mihail Ivanchev
I think this would be good for writing unit tests of private methods.
-Ian On Sun, Nov 6, 2011 at 8:04 AM, Mihail Ivanchev <[hidden email]> wrote: Friend class concept violates basic principles of OO design and encapsulation. Clearly, a private variable is part of the internal state of an object and no other object should access that. When you use friendly classes you say "I have a private var which is not really private, because someone else than I has access" which is in effect an oxymoron. 99,99% of the cases you use friendly variables you have a very bad and wrong design of in your architecture. Almost all cases of apparatent friendship relations are solved by giving the user an external interface / class: -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
Well, it kind of is, but it's the principle that pairs of function names are nicer having the same length. get / set for example
Would crud be the appropriate metaphor, would it make sense for a class to be able to create an instance but not edit it? how about @edit and @read?
On Sun, Nov 6, 2011 at 10:20 AM, Nicolas Cannasse <[hidden email]> wrote: Le 06/11/2011 10:10, Laurence Taylor a écrit : -- haXe - an open source web programming language http://haxe.org |
In reply to this post by bubblebenj
Ok after some more thought, I have a new argument..... which maybe wrong but I will present it so that it can be considered, I don't believe there is a need for give and take... just take. I propose 'give' is not implemented, then @Access is much clearer in its meaning since it only takes, and it will be a lot easier to minimize access. Cheers ;j On 6 Nov 2011, at 12:42, benjamin Dubois wrote: Also it's nice to be able to give friendship to a whole package :D -- haXe - an open source web programming language http://haxe.org |
Actually this should not be a macro this should be like "using" and use the keyword "taking", then using could be refined to be able to be applied in more function/var way as well.
On 6 Nov 2011, at 14:12, [hidden email] wrote:
-- haXe - an open source web programming language http://haxe.org |
In reply to this post by bubblebenj
I do not restrict access with the interface. Instead the interface is what the user will get and be able to manipulate. The implemenation of the interface is private and will not be accessible to the user so I can implement whatever pattern I wish to modify the inner state. For example the implementing class (because it's hidden) could provide PUBLIC methods for the rest of the internal implementation to modify it's state. Thus, the friendship is not needed anymore and the problem is resolved using standard OO practices. Friendship could be viewed as a shortcut that you use as an excuse not to finish the design of an architecture. An object should never allow anyone to modify it's inner state. Otherwise we cannot talk about OO anymore.
On Sun, Nov 6, 2011 at 2:43 PM, benjamin Dubois <[hidden email]> wrote: I still don't get how you restrict access with interface. -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
Hi,
I like the framework. I think "grant access" is slightly more correct than "give access", and possibly reads slightly better with the package nouns. If it were "control" then I think "assume control" would convey the meaning of forcing your will on the control - not so sure about "assume access" Perhaps "hijack" would convey a suitably dangerous activity? : grant/hijack Another pair that may be easy to remember: trust/trustedBy Implies that either party can declare their trust. Hugh > Le 06/11/2011 10:10, Laurence Taylor a écrit : >> @:give and @:take? It also happens to be an English idiom. > > "giving access" seems natural to me but "taking access" seems a bit od. > I'm not a native speaker. > > Best, > Nicolas -- haXe - an open source web programming language http://haxe.org |
In reply to this post by Nicolas Cannasse
Hi Nicolas.
Sounds great, glad to see that haXe becomes more suitable for library development :D I'm missing a general concept which is not available yet. Currently it's all about opening up and give/take access to members even more. What about restricting access to members? Currently real private members cannot be declared which gives access to internal modules. What about a @:restrict like construct to restrict the access to a 'private' level. A parameter could look like this: @:restrict(my.pack) which means "don't allow access from members which are not in this package". Another problem using this extended macro approach: Most languages do not have a feature like "friend" classes. Does that mean if I declare a method private and any @:give, @:take, @:access is set to a member, it becomes public and the compiler does the rest checking? I'm also in fear of the @:access approach. Isn't it all about restricting rather than opening in OOP (encapsulation)? @:access(my.secure.LicenseSystem.unlockEverything) allows everyone to use internal secret methods which are not designed to become public. A 2 way contract would be a more secure way: The class providing a private method, should make it accessible via @:give, and the other method should gain access via @:access. @:access to an element not marked with @:give will not work. Yesterday I started working on a C# code generator using macros and encountered a lot of problems against visibility. Currently all private members are 'protected virtual'. For a C# library/application that's quite bad design. Additionally stuff like friend classes are not available in C#. What are the plans how the resulted code will look like? Greetings Daniel |
In reply to this post by Nicolas Cannasse
Hey Nicolas,
I really like this approach. What do you think about using a keyword other than "give"? @:allow (com.eclecticdesignstudio) private var myProperty:Dynamic; @:public (com.eclecticdesignstudio) private var myProperty:Dynamic; On Sun, 06 Nov 2011 01:59:38 -0700, Nicolas Cannasse <[hidden email]> wrote: > Hi, > > Following recent discussions about the way you should be away to access > other classes private variables and methods, I've written a draft about > a new proposed feature called "Access Control" : > > http://haxe.org/manual/acl > > Thank you for your feedback, especially about the naming choice of > @:give/@:access which I'm not 100% happy with, but it's not very easy to > find better (please prove me wrong). > > Best, > Nicolas > -- Using Opera's revolutionary email client: http://www.opera.com/mail/ -- haXe - an open source web programming language http://haxe.org |
In reply to this post by danielku15
Hi Nicolas,
as I said earlier, IMHO having to actually use this feature is a code smell. The question I have is: will this work with interfaces? Can I say: interface IFoo { @:give(foo) function darkFooMagic():Void; } class Foo implements IFoo { @:give(foo) function darkFooMagic():Void; } And the compiler enforces that darkFooMagic has at least @:give(foo) access (but public should also be ok). Plus, I am wondering how this will be represented at macro-time. Because having this just somewhere in the meta-data doesn't seem right, while at the same time I wouldn't want to treat this as an extra case. Personally, I think this will overcomplicate things. A lot of people will be using this instead of just creating a clean type hierarchy. Accessing something that isn't public is a hack. No matter how pretty a system you use for it. As I said, the weird thing about private structures is simply, that it's not evident and that it kind of overloads the meaning of field access control (because private usually means "can't touch this" but suddenly changes its meaning to "can touch this, even if it's actually forbidden"). I think the solution you are proposing now overshoots the mark and substitutes a slightly quirky yet weirdly elegant system with a "dangerously powerful" one. Splitting the choice between public and private at the declaration site with a arbitrarily distinctive choice at both declaration and callsite seems like a big deal to me. It's almost irrelevant how the tags are named. The key questions are: - Do we need such a system? - Will this work well with all other language features? - Isn't such a system promoting poor coding practices? IMHO allowing something like private(someInstance.privateField) or $private(someInstance.privateField) or someInstance.$privateField seems dead simple to me, and good enough. And technically it doesn't really require new syntax. Nor a complex system that complicates access control. -- haXe - an open source web programming language http://haxe.org |
Free forum by Nabble | Edit this page |