names [Was: Approach of new Object methods in ES5]

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Sun Apr 18 05:43:29 PDT 2010


Hello David,

Saturday, April 17, 2010, 8:01:48 PM, you wrote:

>> But I meant not only naming convention, but that by this naming
>> convention this properties (symbols) will be hidden -- just like in
>> Python, when "_" and "__" properties become unavailable outside...

> You still haven't specified what "outside" means. What does get to
> see a hidden name and what doesn't?

If to take the mentioned above Python with its naming convention,
then:

class A(object):

    def __init__(self):
      self.public = 10
      self.__private = 20

    def get_private(self):
        return self.__private

# outside:

a = A() # instance of A

print(a.public) # OK, 30
print(a.get_private()) # OK, 20
print(a.__private) # fail, available only within A description

# but Python just renames such properties
# _ClassName__property_name
# and by this name this properties are 
# abailable outside

print(a._A__private) # OK, 20

This implementation shows that encapsulation is an increasing of
abstraction, but not just a hiding related to "hey, ... just look
for a private member variable called 'count'!". From this viewpoint
Python's implementation doesn't fit.

The same e.g. in Ruby: we can define "private" and "protected"
properties/methods, but on the other hand we have special meta
methods such as "instance_variable_get", "instance_variable_set",
"send" and other which allows to get access to encapsulated data.

class A

  def initialize
    @a = 10
  end

  def public_method
    private_method(20)
  end

private

  def private_method(b)
    return @a + b
  end

end

a = A.new # new instance

a.public_method # OK, 30

a.a # fail, @a - is private instance var without "a" getter

# fail "private_method" is private and
# available only within A class definition

a.private_method # Error

But, using special meta methods -- we have access to that encapsulated
data:

a.send(:private_method) # OK, 30
a.instance_variable_get(:@a) # OK, 10

This implementation also shows that it is mostly about abstraction --
as a convenient sugar to help programmer more abstractly describe the
system, and less about "no one should see this data".

I wrote about it briefly: http://bit.ly/bnDTkW

But of course, mentioned above implementations aren't the sample and
ECMAScript can (and even should) provide its own. And if there there
is ability to manage it without any access from the outside -- this is
also good.


>> Then I have to see more examples.

> 1) Publishing private names ruins abstraction

> Let's say you create a library and share it with some people. Then
> in version 2 of your library, you introduce a new feature, which
> uses an internal private property called "count". One of your
> clients figures out that you used this private name and writes a
> blog post saying "hey, if you want to figure out whether the library
> is greater than version 1, just look for a private member variable called 'count'!"

> Now you have 100,000 clients depending on the fact that you have a
> private property called "count." You decide for version 3 that you'd
> rather call it "elementCount" but you can't get rid of the private
> name because your customers have already relied on it.

Yes, Dave, I understand all this. But you here mostly talk about
naming dependency. And in this case you (probably) will suggest to
have a public getter for this private local "count" var, yep? Yes,
this is quite logical and true. But this naming dependency can appear
again if you rename already public method from "getCount" to
"getElementCoutn". All your 100,000 clients also will break the code.

But, yes, encapsulation of /helper auxiliary data/ is increasing of
abstraction and the main goal that users still have some public
/unchangeable from version-to-version/ getter getCount while we can
change everyday our private helper auxiliary data -- will we use
"count" name or "elementCount" (or even both of them) -- should be
abstracted from the user.

Moreover, I mostly meant examples of the current approach of "Name"s --
want to see how useful/elegant will it look from the syntax viewpoint.


> 2) Publishing private names creates namespace pollution

> Library A adds a private "count" property to some shared object.

> Library B also adds a private "count" property to the same object.

> They are both developed separately.

> Now Client C wants to use both Library A and Library B. Let's
> arbitrarily say it adds A first, then B. Library B fails with an
> error because it tries to use the private "count" property, which it
> doesn't have access to because Library A already claimed it.

Yes of course. These are different things: helpter auxilary data and
public properties for /any/ public object. From the first viewpoint
(private auxilary data) -- of course A and B libs should use their own
"namespace/private state object" for this purpose. But if the goal to provide
that "count" property to exactly some shared /public/ object -- that's
OK if B will fail. The full responsibility for this is only on Client
C but not on A and B libs. Again -- only if that libs want to provide
exactly /public/ augmentation.

That's again what I mentioned -- if I'm free from all consequences of
augmentations of buil-ins (which are: (1) using several 3rd-party libs,
(2) enumeration with for..in over augmented objects without control of
{DontEnum}/[[Enumerable]]) -- it's /very/ convenient and useful to
augment built-in prototypes and use plugged-in functionality as it
would be native for this objects. The same approach is
used in Ruby libs e.g. which the same as ECMAScript (but in contrast
with Python) allows augmentations of built-in classes.

>> And nevertheless, encapsulation in
>> its main purpose -- is increasing of abstraction. But you're talking about
>> already *security* hiding.

> Absolutely not. What I'm talking about is abstraction, *not*
> security.

OK.

> The purpose of abstraction is to support modularity, i.e.,
> to eliminate dependencies between separate units of modularity so
> that their implementations are free to change. If you publish your
> private names, you create a point of dependency between modules and
> make it harder to change code. None of this is talking about security.

Yes, true, agreed.

> Of course, publishing private names is bad for security as well!

Yep, but if programmers wants to get access to encapsulated data --
this is the wish of the programmer and only the programmer takes full
responsibility for it. Although, it is possible to talk about bad
practice programming, yep.

In other case -- if to forbit anything -- we go to static strict language
already, which has another ideology.

Thanks,
Dmitry.



More information about the es-discuss mailing list