POV-Ray : Newsgroups : povray.off-topic : This is the sort of brokenness... Server Time
7 Sep 2024 05:09:36 EDT (-0400)
  This is the sort of brokenness... (Message 131 to 140 of 164)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 16:51:49
Message: <49c401e5$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> He's saying that putting "private:" before the variables in a class 
>> declaration is equivalent to naming private variables with an underscore. In 
>> the first case, the compiler warns you if you use a private variable by 
>> mistake. In the second case, it's obvious from inspection. If you have
>>     x._y
>> in your code, you're doing something wrong. :-)
> 
>   Btw (not flaming here), what would be the naming convention for nested
> classes? Take, for example, this kind of situation, in C++ code:

Python is kind of funky in this respect. Nested classes (or functions, or 
etc) don't have access to the private variables of the classes they're 
nested in.  They can only get locals, globals, or built-ins. A lambda 
expression can, but that's not a separate class as such, but just an unnamed 
function.

Depending on which naming convention you're talking about, class beta nested 
inside class alpha would be alpha.beta (if it's a public class), or 
alpha._beta if it's a private class.

In python, classes are values just like strings and lists and such. You can 
even instantiate classes without using the normal syntax, just by invoking 
the appropriate constructor for type "class". The syntax
    class abc:
       ...
just invokes that constructor and assigns the result to the variable abc 
(which creates the variable in that namespace if it doesn't already exist).

So if you nest alpha within beta like this
class beta:
    static_one = 1
    static_two = 2
    def beta_add(self,x,y):
       return x + y
    class alpha:
      root = 27
      def alpha_add(self,x,y):
         return x + y + root
then you get beta.static_one and beta.static_two and beta.beta_add and 
beta.alpha. You also get beta.alpha.root and beta.alpha.alpha_add.
Alpha can't access beta.static_one without using a dot. Beta can access 
alpha (as in "new alpha" sort of thing) without a dot, because alpha is a 
static variable of class beta.

But the namespaces that routines in alpha can access don't include the 
namespace that beta uses, and vice versa.

Hence, to get to alpha from outside of beta there, you need to say beta.alpha.

If you want alpha to be private to beta, so beta is (say) your linked-list 
class and alpha is a single link, you use "class _alpha:" instead, which 
indicates that beta._alpha is meant to be private to beta.

If you want alpha to be public, you name it "class alpha:" and others refer 
to it as beta.alpha.

Does that answer it? I probably gave way more details than you were actually 
asking about. :-)

The same naming convention holds for what you'd call "member variables" in 
C++, member functions, static variables/functions, nested classes, etc. 
Everything gets assigned to a variable. If you want gamma to implement the 
same foobar function as delta does, you can just write
    gamma.foobar = delta.foobar
and they're both the same function afterwards.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Warp
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 17:30:25
Message: <49c40af0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Does that answer it? I probably gave way more details than you were actually 
> asking about. :-)

  I actually didn't understand your answer. There might have been some
miscommunication.

  Let me restate:

  There's a class named 'OuterClass', which has a public interface for
everything else to use, and a private part which is used only by 'OuterClass'
itself, and should be accessed by anything else.

  This private part declares another class named 'InnerClass'. This class
in question is part of the private implementation of 'OuterClass', and thus
should not be used in any way from the outside. However, 'OuterClass' itself
can, naturally, use it as usual.

  However, 'InnerClass' itself also has a public and a private part: The
public part defines the interface for 'OuterClass' to use. The private
part is for the internal implementation of 'InnerClass' itself, and shouldn't
be accessed by 'OuterClass'.

  The question is: If we are using a naming convention to denote public
and private data, how do you name 'InnerClass' and its private members?

  Since 'InnerClass' is part of the private implementation of 'OuterClass'
and thus should be used from the outside, I assume that the convention is
to call it '_InnerClass' (or whatever). The underscore denotes "don't
use this class from outside 'OuterClass', because it's private".

  How how do you name the members of this '_InnerClass'? All of its
members, even those in the public interface, are part of the private
implementation of 'OuterClass' and thus shouldn't be used from outside,
so do you put underscores in all the members, even public ones?

  What about the private members of '_InnerClass'? How do you differentiate
them from the private members of 'OuterClass'?

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 18:09:14
Message: <49c4140a$1@news.povray.org>
Warp wrote:
>   The question is: If we are using a naming convention to denote public
> and private data, how do you name 'InnerClass' and its private members?

Got it.

OuterClass
OuterClass._private_static_of_OC
OuterClass.public_static_of_OC
OuterClass._InnerClass
OuterClass._InnerClass.used_by_outerclass
OuterClass._InnerClass._Used_only_by_innerclass

Does that clarify?

OuterClass could invoke
    x = _InnerClass.used_by_outerclass

The trick is you shouldn't write "._" as part of a reference. :-)

>   How how do you name the members of this '_InnerClass'? All of its
> members, even those in the public interface, are part of the private
> implementation of 'OuterClass' and thus shouldn't be used from outside,
> so do you put underscores in all the members, even public ones?

Oh, no. InnerClass isn't really "part" of outer class. It's just a class 
that happens to be created while creating InnerClass and assigned to a 
static variable of InnerClass.

Python doesn't have declarations, even of classes and functions and methods. 
It has statements that have lumps of code in them and creates an instance of 
a function object or an instance of a class object, and then assigns it to 
the name you gave the statement.  So there's no real relationship between 
InnerClass and OuterClass, any more than you have a relationship between a 
sphere object and the texture on the sphere. There's a relationship there, 
but it's not a relationship having to do with types, but rather with 
pointers to instance objects.  Kind of like javascript in that respect.

>   What about the private members of '_InnerClass'? How do you differentiate
> them from the private members of 'OuterClass'?

The private members of _InnerClass have _ on the front. _InnerClass can't 
access OuterClass's private or public variables without going through the 
class or instance dot-notation.

InnerClass and OuterClass are two 100% separate and independent classes. You 
could get *exactly* the same result by declaring it this way:

class InnerClass:
    .....

class OuterClass:
    ...
    _InnerClass = InnerClass
    ...
(Except of course now InnerClass has a global name also)

A nested class definition says "Create a new instance of type 'class' and 
assign it to this name in my namespace."  But that doesn't give the nested 
class any access that any other class could have, and vice versa. It's just 
a different name for a class. InnerClass doesn't have anything that points 
to the parent class, so there's no way to get to anything in the parent 
class directly from InnerClass. If the parent class has a global name like 
"OuterClass", then you can refer to that, of course, but there's nothing 
that tells InnerClass it's "part of" outerclass.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Warp
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 18:18:08
Message: <49c41620@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Warp wrote:
> >   The question is: If we are using a naming convention to denote public
> > and private data, how do you name 'InnerClass' and its private members?

> Got it.

> OuterClass
> OuterClass._private_static_of_OC
> OuterClass.public_static_of_OC
> OuterClass._InnerClass
> OuterClass._InnerClass.used_by_outerclass
> OuterClass._InnerClass._Used_only_by_innerclass

> Does that clarify?

> OuterClass could invoke
>     x = _InnerClass.used_by_outerclass

> The trick is you shouldn't write "._" as part of a reference. :-)

  But an outside code could do something along the lines of:

OuterClass::_InnerClass obj; // Assuming the compiler doesn't restrict this

obj.someFunction();

  The first line clearly breaks the privacy contract, but with the second
line it's not so obvious anymore. It's calling a public member of _InnerClass,
but it's intended to be "public" only for OuterClass (because _InnerClass is
part of the private implementation of OuterClass), not for anything else.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 22:38:35
Message: <49c4532b$1@news.povray.org>
Warp wrote:
>   But an outside code could do something along the lines of:
> 
> OuterClass::_InnerClass obj; // Assuming the compiler doesn't restrict this
> 
> obj.someFunction();

That's correct. And no, the compiler doesn't restrict it. I don't know I've 
even heard of a source code tool that warns you about it, altho that would 
seem fairly easy to write, methinks.

Just FYI, the syntax for that would be
   obj = OuterClass._InnerClass()
   obj.someFunction()

OuterClass._InnerClass returns the class itself, since the class is just 
assigned as the value of the variable. Invoking that value with () does the 
equivalent of C++'s "new". Then you assign whatever the constructor returned 
to obj.  Depending on the existence of different functions inside the 
_InnerClass class, you get things like overridden "new" or overridden 
constructors.

And, technically, a constructor doesn't *have* to return an instance of the 
class you invoked, if you override "new" in the class and have it return 
something of a different class. So it's even uglier. :-) Just calling
   obj = OuterClass()
could actually wind up assigning an OuterClass._InnerClass instance to obj.
Handy for factory functions, tho.

>   The first line clearly breaks the privacy contract, but with the second
> line it's not so obvious anymore.

Correct.

On the other hand, it's the same result as if you did something like
obj = OuterClass::factory_method(...)
and factory_method returns an instance of _InnerClass. So it's not really 
something you could enforce there at the compiler level.  (As in, it would 
be hard to enforce at the obj.someFunction() call, but easier at the 
OuterClass._InnerClass access.)

I.e., I'm not sure I'd describe the second line as breaking the privacy 
contract. It's just using a value obtained by breaking the privacy contract. 
But that's just a matter of wording, really.

> It's calling a public member of _InnerClass,
> but it's intended to be "public" only for OuterClass 

Not necessarily. If OuterClass returns an instance of _InnerClass (like, if 
OuterClass is a collection and _InnerClass is an iterator over the 
collection) it might make sense.

> (because _InnerClass is
> part of the private implementation of OuterClass), not for anything else.

If OuterClass never returns instances of _InnerClass, yes, that would be a 
difficult violation of modularity to track down. It's certainly not the best 
way of doing things if you're worried about that sort of thing.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 20 Mar 2009 23:31:47
Message: <49c45fa3@news.povray.org>
Darren New wrote:
> It's certainly not 
> the best way of doing things if you're worried about that sort of thing.

Um, "it" there means "Python's way of handling private variables", not 
"inner classes".  As in, naming conventions aren't the best way of handling 
private members if you're worried about someone violating the privacy.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 21 Mar 2009 03:12:49
Message: <49c49371@news.povray.org>
Warp wrote:
>   And it's getting really tiresome and old that you act all innocent after
> a tirade of C++ bashing, 

Can you do me a favor, for the sake of future conversations?

Can you tell me what I said that you took to be "a tirade of C++ bashing"?

As far as I can see, I've been trying to be factual and honest. You started 
out using derogatory terms like "it's a kludge", and "that's BS", and 
referring to people as "self-taught hackers" and "use a fancy term instead 
of admitting their mistake" and "In Utopia, maybe" and the usual insulting 
hyperbole.

Where did I say anything derogatory about C++? I would like to know what I 
said about C++ that you took to be saying C++ is *bad*. Can you actually 
quote what I wrote that you took to be "C++ bashing", let alone a "tirade"?

As far as I can see, the conversation (once it got to be about modularity 
instead of minimalism) went something like
You: "Modularity is good. Breaking modularity is bad."
Me: "Yes. But everyone breaks modularity in different ways.
    CLOS breaks it by doing A
    C# and Java breaks it by doing B
    Python breaks it by doing C
    C++ breaks it by doing D
    I prefer B over D."
You: "D doesn't count. C++ doesn't break modularity."
Me: "Wild pointers."
You: "Doesn't count - not standard."
Me: "Memset"
You: "Doesn't count - non portable."
Me: "But it still happens."
You: "You're so mean, always bashing C++."

So, in all honestly, I'd really like to know where in the process I said 
something that "bashed" C++, rather than simply comparing its behavior with 
other languages and explaining (in detail) why I preferred the other mechanisms.

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Darren New
Subject: Re: This is the sort of brokenness...
Date: 21 Mar 2009 03:12:55
Message: <49c49377@news.povray.org>
Warp wrote:
>   You can't access the private variable by address. Not according to the
> standard. 

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Section 3.9 paragraph 2, page 60 sheet 74.

#define N sizeof(T)
char buf[N];
T obj ; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std::memcpy,
                            // obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar 
type
// holds its original value


Yet I'm sure at this point that there will be some reason this doesn't count 
as violating modularity. Will it be that it's only a draft of the standard? 
Will it be that it's only true of POD types? Will it be because it only says 
it works for reading and writing all the private variables at once?

-- 
   Darren New, San Diego CA, USA (PST)
   My fortune cookie said, "You will soon be
   unable to read this, even at arm's length."


Post a reply to this message

From: Warp
Subject: Re: This is the sort of brokenness...
Date: 21 Mar 2009 07:42:10
Message: <49c4d292@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Warp wrote:
> >   You can't access the private variable by address. Not according to the
> > standard. 

> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
> Section 3.9 paragraph 2, page 60 sheet 74.

> #define N sizeof(T)
> char buf[N];
> T obj ; // obj initialized to its original value
> std::memcpy(buf, &obj, N); // between these two calls to std::memcpy,
>                             // obj might be modified
> std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar 
> type
> // holds its original value


> Yet I'm sure at this point that there will be some reason this doesn't count 
> as violating modularity. Will it be that it's only a draft of the standard? 
> Will it be that it's only true of POD types? Will it be because it only says 
> it works for reading and writing all the private variables at once?

  By the same logic this would also "break modularity":

T obj;
T obj2 = obj;

  All the data in obj is copied to obj2. This includes all the private data.

  However, the memcpy() version *is* breaking modularity because, as the
text says, it's guaranteed to work only if the object contains scalar
types. If you assume it does, you are breaking modularity.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: This is the sort of brokenness...
Date: 21 Mar 2009 07:59:12
Message: <49c4d690@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Can you tell me what I said that you took to be "a tirade of C++ bashing"?

  A combination of concepts gave me the impression that you were
denigrating the way C++ does thing, while praising how other languages
do it better.

  Maybe you didn't use the word "unsafe" in a derogatory manner, but it
was easy to get the impression. When you said basically that it's not true
that C++ enforces modularity, and proceeded to "demonstrate" that by
trying to give examples of how you can circumvent C++'s semantics by
using low-level pointer casting and arithmetic, it gave the impression
that you were denigrating C++ for trying to do something and failing
miserably. This impression was emphasized by you at the same time telling
how you prefer how other languages do it "right" by having explicit support
for breaking the module interface boundaries, while in C++ you have to
resort to non-standard hacks to do the same. Also your arguments why
someone would even want to break the interface boundaries was not completely
convincing to me. (Your only argument seemed to be "reflection", and my
only experience on it is with Objective-C, where it's done without really
accessing private members from the outside, at least as far as I have had
to deal with it.) When you wrote that C++ is the only unsafe OO language
you know of, it sounded like you were bragging how *all* other OO languages
are better than C++, which gives the impression that you are telling that
C++ is the worst possible OO language in existence.

  I apologize if I overreacted.

-- 
                                                          - Warp


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.