Your position is clearly understood. IMO the problem is in the
semantic, not in in the correctness / non-correctness of a programming
paradigm.
Besides, I don't see any problem with understanding what does the
"encapsulation" term (in computer science) mean.
Any JavaScript program has three main stages of the life
cycle:
1) idle stage (source stage)
That is the stage of a program being say open in an editor or simply
stored as a file client/server side.
2) parsing stage
This is the stage of the source being fed to the parser
3) execution stage
I guess it doesn't need to be explained
Let's say -- not only JavaScript, but many other languages have such
stages (I'll mention the Ruby soon to show you again -- how we can
easily and _dynamically_ affect the code, getting access to the
encapsulated data if needed)
Of course, if we have the case when a programmer do this often (of
without understanding -- that is more essential), then it is possible to
talk about /bad programming stylistics/.
In your posts you are talking about the idle stage and the
"abstraction encapsulation" as it applies to that stage.
Not only the "idle" stage (by your terminology). In completely dynamic
language with mutable objects we can affect the code dynamically at
runtime. Take any such language -- Ruby, Python, ECMAScript, etc.
For this
stage and this kind of encapsulation your arguments are correct.
OK. But I should again mention -- I didn't prove anything, I just explained.
Indeed, the abstraction encapsulation appeared as a measure of
protection of programmers from programmers,
Yeah, that's right -- as a good helper for more abstractly and therefore
-- more quality build a system -- with a (possibly) complex and powerful
internal state, but with the convenient public API for a user of our
system. And this internal state (an auxiliary data) is encapsulated from
the user, making using the system really convenient and all details are
transparent. I should underline the whole this sentence -- this exactly
is called as an encapsulation in the computer science.
so the library would be
used in the documented way and not over different "undocumented
features" ("Undocumented features of ..." once was a very popular
title at DOS/Windows 3.x times).
Yeah, I remember that titles
The usage of undocumented features
and unfrozen interfaces may be very effective for a particular task in
comparison with officially exposed methods.
Maybe, but such cases (if possible) should be avoided in the good
stylistics. Notice, nevertheless, I don't mention security.
Yet such usage is a
ticking bomb in case of internal library changes.
Yep. Only the programmer is responsible for that. If he want to use a
system not by the "rules", he _may_, but -- the full responsibility is
on him. If something goes wrong -- only he will rewrite his system
correctly using special public interface to talk with the system.
That's it -- the system has its right -- to change at any time its
internal state. At the same time, if a programmer knows the system
completely and knows /how/ and /when/ it will look like after the
changes of some internal state, he can affect this internal state, but,
repeat, with full responsibilities for that.
I mention the Ruby again. I already showed you an example how a
programmer can affect internal instance variables (in Ruby they prefixed
with @ sign -- analog of using `this.` in other languages).
Alternatively, Ruby has ability to send messages to /private/ state of
an object:
class A
def initialize
@a = 10 # instance variable without getter/setter
end
def test
return @a + private_method()
end
private
def private_method
return " from private"
end
end
a = A.new # an instance
a.a # error, there is no getter for @a
# the general getter of instance
# internal (sic!) encapsulated variables
a.instance_variable_get
@a) # 10
# public method has access
# to the private method
a.test() # "10 from private"
# at the same time "a" has
# no access to the "private_method"
# from the outside of the "A" class definition
a.private_method() # error, access to private method
# but (sic!) using the general "send"
# method we can access this encapsulated state
a.send
private_method) # OK - " from private" is returned
Now tell me. The author of Ruby -- Yukihiro Matsumoto <URL:
http://en.wikipedia.org/wiki/Yukihiro_Matsumoto> -- could he /by his own
hands/ just "kill" his language and provide such "insecure" methods?
Could he just don't think about anything and create such "ugly" language
which (oh-o-o..) has no /"private" keyword for "security"/? Or maybe, he
just knew _what is_ encapsulation?
So here the
abstraction encapsulation came. Can anyone still alter the program on
its idle stage, say private to public etc? Of course she can.
By the way, why do you used "she" word? I'm just interested from the
English language position. Why not "he"?
Here
digital signatures, hash codes and user agreements come into play. So
I can alter or completely redo a 3rd party library but it eliminates
my possibility to complain if anything goes wrong, it eliminates my
rights for support and in most cases it violates the user agreement I
had to accept. So the explicit manual change of a 3rd party program
lies beyond any programming matters, in the legal domain.
Yes, true.
The issue with the abstraction encapsulation - which is rightly
criticized by you - is that at some moment some programmers wrongly
took the possibility of the "back door" access as their
responsibility.
Yes.
Other words if method getXY() has internal _foo
accessible from outside, and by setting _foo to something makes
getXY() behave wrongly then it is by definition my own holly
obligation to protect _foo from side access. It is not. I may do it,
or I may let anyone to "shoot his leg" and screw them.
But please notice, I don't say a word that "strong encapsulation" --
i.e. without _any_ ability to affect the internal state is bad.
Vice-versa -- it's even better helper for a programmer, because can
faster catch errors. But, he will catch the same errors and in e.g.
Ruby's implementation -- where will be such errors with /direct/ using
of an internal state.
So for the abstraction encapsulation we seem to have no points to
argue.
Yeah, seems so. OK.
Just want again to notice, that if we sure that some internal state
won't be change in the future, then (IMO -- and logically) there is no
/any/ need to make it encapsulated providing hiding of /absolutely
non-abstract/ entities. This can be the same ridiculous as not to
understand the language (yep, e.g. as using === with `typeof' comparing
the result with strings).
I mean if you sure that in future `foo' datum won't be changed, then:
function getFoo() {
return foo;
}
is just /big misconception of an encapsulation/. Of course, if we
/predict/ such changes and in future `foo's getter will be more complex,
then we can _reserve_ such _non-abstract_ getter and this is completely OK.
However, it's just my meaning and regarding the particular
implementation, e.g. ECMAScript. Because again in Ruby, this is in the
_core ideology_ -- an internal datum could/should have a getter/setter
-- and in general case these getters/setters can be the same
non-abstract just returning the value of that internal state (in the
mentioned example on Ruby above for @a e.g. -- def a; return @a; end).
But at the same time (having such ideology) you saw the mechanism of
getting access to the internal data.
Or, another example where such absolutely non-abstract getters/setters
can make sense. This is Java. If I remember correctly, it recommends to
use always getter/setter for a "private" variables. But -- what's the
most funny -- it relates to the implementation of the Java: there a.foo
and a.getFoo() can (in some specific cases) return /different/ results
-- because methods are polymorphic, but properties not (if will be
needed a complete example of such ambiguity, let me know). So for the
/correct/ behavior they recomment always use getters for that. Although,
I've heard, and in Java community there are people which don't see a
sense in such non-abstract (read === "useless") encapsulation.
I was arguing about the execution stage and the security
encapsulation which is a whole different issue.
The term "security encapsulation" is odd, but at the same time
widespread in its misconception. I can imagine e.g. "security measures"
concept. Yes, software could/should be secure -- depending on our needs.
If we have a dynamic language with mutable objects which can be altered
at runtime, and at the same time we openly provide such ability -- using
e.g. "console" or "javascript:" pseudo-protocol, then it is not so
responsible not to check the data also on the server side (in this case,
the JavaScript is just an convenient addition).
But sure, a "private" isn't for security, but for programmers.
You put a "private" keyword? -- a hacker will alter the bytecode.
You have some compiled program? -- the hacker will alter it with
HEX-editor and won't even see on your "private" keyword.
You afraid that the hacker will change your private "_foo" which is used
in "setFoo" -- don't worry -- he will change completely "setFoo" instead
(the language is dynamic, forgot? -- or maybe you'll suggest to make JS
static? -- it won't help also).
You afraid that somebody will alter your JS object via console? -- the
hacker will sniff a traffic on the net level and don't even see your
JavaScript object with a "private" keyword.
So, I repeat, other measures are used for software security and safety,
but not the "private" keyword.
But, of course, encapsulation sugar in OOP such as "private",
"protected" and "public" is a good sugar (and "strong" version can be
even more convenient for someone) and a good helper for the _programmer_
-- therefore this sugar was invented. Thus, notice, "protected" is just
a consequence of some paradigm.
Dmitry.