Re: Operator precedence [message #185075 is a reply to message #185067] |
Tue, 25 February 2014 21:01 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/25/2014 11:56 AM, Ben Bacarisse wrote:
>>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>>
>>>> On 2/24/2014 11:32 PM, Ben Bacarisse wrote:
>>>> > Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>>> >
>>>> >> For instance a 32 bit C compiler will have different results than a 64
>>>> >> bit C compiler, even if both are run on a 64 bit machine. And even
>>>> >> different 32 bit C compilers can have different output. For instance,
>>>> >> in a 32 bit C compiler, an int can be 8, 16, or 32 bits long - all
>>>> >> within the specs
>>>> >
>>>> > No, C does no permit int to be less that 16 bits wide -- 8 is not
>>>> > allowed.
>>>>
>>>> Actually, the ANSI C spec DOES allow it. The spec sets no hard
>>>> minimum or maximum for the size of any of the numeric values. C can
>>>> still run on 8 bit processors, also (as in imbedded systems).
>>>
>>> It seems odd to be disagreeing about easily verifiable facts. ANSI C is
>>> often used to refer to the first C standard (1989), in which case look
>>> at section 2.2.4.2 "Numerical limits". If you mean the current ANSI
>>> standard, that's ISO/IEC 9899:2011 and the section you need is
>>> "5.2.4.2.1 Sizes of integer types <limits.h>". (You also need the
>>> section from each that states that the constraints imposed by limits.h
>>> apply to both hosted and free-standing implementations.)
>>>
>>
>> As I said before - I wore my ANSI C standard out and tossed it quite a
>> while back. But even then it did not specify a minimum of 16 bits for
>> an integer. There are still 8 bit processors and compilers out there.
>>
>>>> >> (which only states the length of an int is >= the
>>>> >> length of a short, and <= the length of a long). So it is entirely
>>>> >> possible one C compiler will have a 16 bit int, while another has a 32
>>>> >> bit int. And both are within the C spec.
>>>> >
>>>> > Yes, but the language gives minimum guarantees which can be used to
>>>> > permit code to be ported. It also (often) explicitly says where there
>>>> > is no guarantee. For example, shifting right by the width of the type
>>>> > being shifted is explicitly "undefined". It's useful to know that,
>>>> > because you can simply avoid the situation in the first place. That's
>>>> > simpler that testing it, seeing that it does what you expect, and then
>>>> > finding that it fails on some other hardware.
>>>>
>>>> The only minimum is that an int must not be smaller than a short.
>>>
>>> No, there are others -- in particular, a minimum range of representable
>>> values for each of the standard integer types. For int it is from
>>> -32767 to +32767.
>>>
>>
>> Then please tell me how an 8 bit compiler can be ANSI Standard? There
>> are some out there. It's been a while since I did any work on one, but
>> I know of several embedded systems which are still in use (and being
>> updated).
>
> It's not necessarily impossible to implement 16bit operations on an 8bit
> machine. I did this long ago on a 6510, and actually it was rather simple.
>
>> I have my own problems with PHP - for instance, it is entirely possible
>> to create an object without calling a constructor - a violation of OO
>> principles. But I work around it.
>
> How is it possible to create an object without its constructor (if
> defined) being called?
>
Load the object from the $_SESSION. The constructor will not be called.
However, the constructor is called when the original object was created,
and the destructor called when the original object goes out of scope.
The destructor is also called when the object loaded from the $_SESSION
goes out of scope.
The result is one constructor call and two destructor calls. A
violation of OO principles.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Operator precedence [message #185078 is a reply to message #185065] |
Tue, 25 February 2014 21:08 |
Ben Bacarisse
Messages: 82 Registered: November 2013
Karma: 0
|
Member |
|
|
Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
> On 2/25/2014 11:56 AM, Ben Bacarisse wrote:
>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>
>>> On 2/24/2014 11:32 PM, Ben Bacarisse wrote:
>>>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
<snip>
>>>> > Documentation indicates what you CAN do - not what you CAN'T do. This
>>>> > is true of languages, databases, spreadsheets and about anything else
>>>> > around.
>>>>
>>>> What can you do with the ',' operator? From the PHP documentation:
>>>
>>> Where in the PHP manual does it say ',' is an operator?
>>
>> "A full list of PHP operators follows in the section Operator
>> Precedence." (which is the section immediately following)
>>
>> That list includes ',' as you yourself stated:
>>
>> "It is an operator, as indicated by its appearance in the table of
>> operators. Operators are not limited to +-*/.".
>>
>> But if that is no longer your position, then we are in agreement.
>>
>
> OK, it does show up in the operator precedence table. But it also
> says "many uses". It doesn't define those uses in the table; it
> doesn't tell you what you can't do.
Nor what you can do. The manual shows all sorts of places where commas
are used but none of the fit the description of an operator as given
else where in the manual.
>
>> <snip>
>>>> As to your general point, the C language standard is an excellent
>>>> example of documentation that says both what you can do and what you
>>>> can't do.
<snip>
>>> No, the C specification does NOT say what you cannot do.
<snip>
>> How many examples would you like? For example, the C standard gives a
>> grammar for expressions and then, for each operator, it gives
>> constraints on that general form. The grammar permits 1 = 1, but the
>> constraints on the = operator state that the expression on the left hand
>> side must be a modifiable lvalue. The upshot is that you can tell what
>> forms of expression are and are not permitted. In particular, C does
>> not permit (cond ? a : b) = expr; but C++ does.
>
> Exactly. It tells you what you CAN do. It does not tell you what you
> cannot do.
We could waste a lot of time going back and forth about what is a
statement about what can be done, and what is a statement about what
can't be done. The long and the sort of it is that PHP has restrictions
on how some operators can be used which are not documented. That, in
your interpretation of things, means that the manual fails to tell you
what you *can* do. According to my view, it fails to tell you what you
can't do. The effect is the same -- undocumented cases.
<snip>
>>>> > [...] For instance,
>>>> > in a 32 bit C compiler, an int can be 8, 16, or 32 bits long - all
>>>> > within the specs
>>>>
>>>> No, C does no permit int to be less that 16 bits wide -- 8 is not
>>>> allowed.
>>>
>>> Actually, the ANSI C spec DOES allow it. The spec sets no hard
>>> minimum or maximum for the size of any of the numeric values. C can
>>> still run on 8 bit processors, also (as in imbedded systems).
>>
>> It seems odd to be disagreeing about easily verifiable facts. ANSI C is
>> often used to refer to the first C standard (1989), in which case look
>> at section 2.2.4.2 "Numerical limits". If you mean the current ANSI
>> standard, that's ISO/IEC 9899:2011 and the section you need is
>> "5.2.4.2.1 Sizes of integer types <limits.h>". (You also need the
>> section from each that states that the constraints imposed by limits.h
>> apply to both hosted and free-standing implementations.)
>
> As I said before - I wore my ANSI C standard out and tossed it quite a
> while back. But even then it did not specify a minimum of 16 bits for
> an integer. There are still 8 bit processors and compilers out there.
I gave a reference to the relevant section, and I quoted (below) the
minimum rage that was specified. It been the same from the very first
ANSI standard to the latest ISO standard. The copy you thew out should
have that text just like every other copy. I don't see what more I can
do.
<snip>
>>>> Yes, but the language gives minimum guarantees which can be used to
>>>> permit code to be ported.
<snip>
>>> The only minimum is that an int must not be smaller than a short.
>>
>> No, there are others -- in particular, a minimum range of representable
>> values for each of the standard integer types. For int it is from
>> -32767 to +32767.
>
> Then please tell me how an 8 bit compiler can be ANSI Standard?
By implementing 16-bit ints (or wider) either directly by the code
generator or by calling functions. But the situation is worse than you
think. Every version of the C standard has required that long int have
at least 32 bits. A conforming compiler on an 8-bit processor must
implement a 32-bit integer type as well.
<snip>
>>>> > The PHP doc shows you what combinations are permitted. You are asking
>>>> > about what is NOT permitted.
>>>>
>>>> Yes, because that is part of the specification of the language. Aren't
>>>> you curious to know what expression forms are permitted on the left of
>>>> an assignment? Would you not find a grammar for PHP to be a useful part
>>>> of the documentation? These thing seem unexceptional to me.
>>>
>>> No, the specification of a language states only what is allowed. For
>>> instance, the C++ spec specifies which operators may be overridden.
>>> It does NOT specify that the '.' operator may not be overridden.
>>
>> Are you just saying wrong things to wind me up? Section 13.5
>> "Overloaded operators" of the current C++ standard says:
>>
>> "The following operators cannot be overloaded:
>> . .* :: ?:"
>>
>> Similar wording exists in the 1998 and 2003 standards.
>
> That has changed in the standard, then. It used to not specify those
> operators which cannot be overloaded.
The wording is in every version of the C++ standard that I have seen,
and it even predates the standard. My copy of Ellis and Stroustrup's
"The Annotated C++ Reference Manual" (1990) has exactly the same wording
on page 330.
<snip>
> If you want to produce a "rigorous standard", you are free to do
> so. But standards are mainly for compiler developers; since there is
> only one, I don't see a need for it (and I doubt ZEND would pay any
> attention to it, anyway).
I am sure they wouldn't. PHP is (to a first approximation) a single
implementation language, and so the source code for that implementation
is the final reference manual. That's how it is possible to be sure
that, at the moment, you can't use ',' as an operator in a general
expression. You can scan the grammar to see all the places where a
comma is permitted and (pretty much) exactly what it does in all those
cases.
>> <snip>
>>> Please show where in the manual it shows you can use the ',' operator
>>> like you want.
>>
>> I don't want to use it in any particular way. In that, the manual is
>> 100% correct because it says nothing at all about how one might use ','
>> in the way it describes operators as working. Bun I was just querying
>> your statement that it is one. If you don't think it's an operator, we
>> are in agreement about that.
>
> OK, I will change my position and agree it is an operator. But it
> cannot be used anywhere you want.
I can't follow this. But really, does it matter one iota if it has one
that you can't use (except in few specially documented places) or if it
doesn't have one at all?
--
Ben.
|
|
|
Object constructors/destructors (was: Operator precedence) [message #185079 is a reply to message #185075] |
Tue, 25 February 2014 21:19 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> I have my own problems with PHP - for instance, it is entirely possible
>>> to create an object without calling a constructor - a violation of OO
>>> principles. But I work around it.
>>
>> How is it possible to create an object without its constructor (if
>> defined) being called?
>>
>
> Load the object from the $_SESSION. The constructor will not be called.
>
> However, the constructor is called when the original object was created,
> and the destructor called when the original object goes out of scope.
> The destructor is also called when the object loaded from the $_SESSION
> goes out of scope.
>
> The result is one constructor call and two destructor calls. A
> violation of OO principles.
Um, I'm not sure whether this is a violation of OOP principles. Storing
an object in the session requires serialization of the object, what is
somewhat comparable to cloning an object. So actually, you're not
working with the *same* object.
Anyway, you can work around these issues by using the magic methods
__sleep() and __wakeup(), as you probably know. :)
--
Christoph M. Becker
|
|
|
Re: Operator precedence [message #185080 is a reply to message #185078] |
Tue, 25 February 2014 21:29 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Ben Bacarisse wrote:
> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>
>> If you want to produce a "rigorous standard", you are free to do
>> so. But standards are mainly for compiler developers; since there is
>> only one, I don't see a need for it (and I doubt ZEND would pay any
>> attention to it, anyway).
>
> I am sure they wouldn't. PHP is (to a first approximation) a single
> implementation language, and so the source code for that implementation
> is the final reference manual. That's how it is possible to be sure
> that, at the moment, you can't use ',' as an operator in a general
> expression. You can scan the grammar to see all the places where a
> comma is permitted and (pretty much) exactly what it does in all those
> cases.
There is at least one other important implementation of PHP, namely
HHVM[1], so I wouldn't call PHP a single implementation language. IMHO
it would be wise to specify the language formally, before
implementations may drift apart.
[1] <http://www.hhvm.com/blog/>
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185081 is a reply to message #185079] |
Tue, 25 February 2014 21:32 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> I have my own problems with PHP - for instance, it is entirely possible
>>>> to create an object without calling a constructor - a violation of OO
>>>> principles. But I work around it.
>>>
>>> How is it possible to create an object without its constructor (if
>>> defined) being called?
>>>
>>
>> Load the object from the $_SESSION. The constructor will not be called.
>>
>> However, the constructor is called when the original object was created,
>> and the destructor called when the original object goes out of scope.
>> The destructor is also called when the object loaded from the $_SESSION
>> goes out of scope.
>>
>> The result is one constructor call and two destructor calls. A
>> violation of OO principles.
>
> Um, I'm not sure whether this is a violation of OOP principles. Storing
> an object in the session requires serialization of the object, what is
> somewhat comparable to cloning an object. So actually, you're not
> working with the *same* object.
>
> Anyway, you can work around these issues by using the magic methods
> __sleep() and __wakeup(), as you probably know. :)
>
Yes, it is a violation. When the script starts, the object is
serialized in the $_SESSION. But it does not exist in the script.
Creating it requires a constructor call. OO principles require exactly
one constructor call and one destructor call for every object created.
Note these may be explicit or implicit, and the functions may be noops,
but the calls must still be made. That is not the case here; you get
one constructor call and two destructor calls.
I know of no other OO language which would allow this.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Operator precedence [message #185082 is a reply to message #185032] |
Tue, 25 February 2014 21:45 |
GS
Messages: 3 Registered: February 2014
Karma: 0
|
Junior Member |
|
|
Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> wrote:
> Ben Bacarisse wrote:
>
>> Thomas 'PointedEars' Lahn <PointedEars(at)web(dot)de> writes:
>>> Ben Bacarisse wrote:
>>>> […] Expressions are built from operators, but is ',' an operator
>>>> in PHP? It appears in the operator precedence table but it isn't an
>>>> operator in an sense that would normally be understood by someone
>>>> familiar with these terms.
>>>
>>> ECMAScript has a “Comma Operator”, too.
>>
>> But my point was the PHP doesn't have one --
>
> But it does:
>
> for ($i = 0, $j = 42; $i < $j; ++$i);
> ^
The comma serves as a separator here, not an operator. It's just
separating items in a list in the same way you do with arguments in a
function call. I think the reason it's in the operator table is just to
clarify that expressions in a list don't need to be bracketed since all
real operators bind more tightly than "," (as you'd expect).
Formally, an operator is just a function which uses infix notation for
its arguments, ie. semantically a OP b = OP(a,b). In fact, some
languages let you define your own operators in exactly the same way as
you do functions. So things like , and ; are not operators (in PHP
anyway) since unlike stuff such as + or > they don't denote functions
which operate on their operands.
The only reason we have operators at all in programming languages is
because the infix notation is familiar and saves us from the LISP hell
of endlessly bracketing everything. Most people find a+b/c easier on
the eye than +(a,/(b,c)). The drawback of the infix notation is it
creates ambiguities that have to be resolved in the language definition
e.g. by assigning a precedence to every operator, or stipulating linear
evaluation, or requiring that every expression containing more than one
operator be bracketed.
This brings us back to what started this thread, namely that in order to
understand the meaning of a PHP expression you need a formal definition
of how expressions are evaluated, including precedence rules. The
existence of a "but..." in the operator precedence documentation subtley
reveals that the formal definition of a PHP expression is not what we
might have thought it to be, as has since been clarified by those
posters who have looked at the source code.
Looking again at the Language Reference page, "Expressions", I think my
original comment that it does not define what an expression is (for
Jerry's benefit I should say "what a PHP expression is"!) still stands.
It gives several examples but falls short of a formal definition which
would tell us whether or not we can use constructions like !$a && $a =
42.
|
|
|
Re: Object constructors/destructors [message #185084 is a reply to message #185081] |
Tue, 25 February 2014 21:55 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > I have my own problems with PHP - for instance, it is entirely
>>>> > possible
>>>> > to create an object without calling a constructor - a violation of OO
>>>> > principles. But I work around it.
>>>>
>>>> How is it possible to create an object without its constructor (if
>>>> defined) being called?
>>>>
>>>
>>> Load the object from the $_SESSION. The constructor will not be called.
>>>
>>> However, the constructor is called when the original object was created,
>>> and the destructor called when the original object goes out of scope.
>>> The destructor is also called when the object loaded from the $_SESSION
>>> goes out of scope.
>>>
>>> The result is one constructor call and two destructor calls. A
>>> violation of OO principles.
>>
>> Um, I'm not sure whether this is a violation of OOP principles. Storing
>> an object in the session requires serialization of the object, what is
>> somewhat comparable to cloning an object. So actually, you're not
>> working with the *same* object.
>>
>> Anyway, you can work around these issues by using the magic methods
>> __sleep() and __wakeup(), as you probably know. :)
>>
>
> Yes, it is a violation. When the script starts, the object is
> serialized in the $_SESSION. But it does not exist in the script.
> Creating it requires a constructor call.
It requires the object to be created in memory somehow, but the defined
constructor function is not called in this case.
> OO principles require exactly
> one constructor call and one destructor call for every object created.
> Note these may be explicit or implicit, and the functions may be noops,
> but the calls must still be made.
When you're cloning an object, its constructor will not be called either.
> That is not the case here; you get
> one constructor call and two destructor calls.
I firmly believe that it wouldn't make sense to call a (user-defined)
constructor when unserializing or cloning an object. A constructor
usually serves to initialize an object -- what already had happened in
both cases.
> I know of no other OO language which would allow this.
Others may.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185085 is a reply to message #185084] |
Tue, 25 February 2014 22:01 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> I have my own problems with PHP - for instance, it is entirely
>>>> >> possible
>>>> >> to create an object without calling a constructor - a violation of OO
>>>> >> principles. But I work around it.
>>>> >
>>>> > How is it possible to create an object without its constructor (if
>>>> > defined) being called?
>>>> >
>>>>
>>>> Load the object from the $_SESSION. The constructor will not be called.
>>>>
>>>> However, the constructor is called when the original object was created,
>>>> and the destructor called when the original object goes out of scope.
>>>> The destructor is also called when the object loaded from the $_SESSION
>>>> goes out of scope.
>>>>
>>>> The result is one constructor call and two destructor calls. A
>>>> violation of OO principles.
>>>
>>> Um, I'm not sure whether this is a violation of OOP principles. Storing
>>> an object in the session requires serialization of the object, what is
>>> somewhat comparable to cloning an object. So actually, you're not
>>> working with the *same* object.
>>>
>>> Anyway, you can work around these issues by using the magic methods
>>> __sleep() and __wakeup(), as you probably know. :)
>>>
>>
>> Yes, it is a violation. When the script starts, the object is
>> serialized in the $_SESSION. But it does not exist in the script.
>> Creating it requires a constructor call.
>
> It requires the object to be created in memory somehow, but the defined
> constructor function is not called in this case.
>
Which is a violation of OO principles.
>> OO principles require exactly
>> one constructor call and one destructor call for every object created.
>> Note these may be explicit or implicit, and the functions may be noops,
>> but the calls must still be made.
>
> When you're cloning an object, its constructor will not be called either.
>
It is in every other language. For instance, in Java, clone() acts like
a copy constructor. C++ doesn't have a clone() method, but it does have
a copy constructor.
>> That is not the case here; you get
>> one constructor call and two destructor calls.
>
> I firmly believe that it wouldn't make sense to call a (user-defined)
> constructor when unserializing or cloning an object. A constructor
> usually serves to initialize an object -- what already had happened in
> both cases.
>
It makes perfect sense. Not everything is necessarily valid in the new
object. For instance, a logging object may require opening the log
file. There are many instances where a resource is no longer available
and needs to be recreated.
PHP's method is only a shallow copy. Copy constructors and the like
were created when a deep copy is required (quite often in other languages).
>> I know of no other OO language which would allow this.
>
> Others may.
>
None that I know of. Please name one.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Operator precedence [message #185089 is a reply to message #185080] |
Tue, 25 February 2014 23:15 |
Ben Bacarisse
Messages: 82 Registered: November 2013
Karma: 0
|
Member |
|
|
Christoph Michael Becker <cmbecker69(at)arcor(dot)de> writes:
> Ben Bacarisse wrote:
>
>> Jerry Stuckle <jstucklex(at)attglobal(dot)net> writes:
>>
>>> If you want to produce a "rigorous standard", you are free to do
>>> so. But standards are mainly for compiler developers; since there is
>>> only one, I don't see a need for it (and I doubt ZEND would pay any
>>> attention to it, anyway).
>>
>> I am sure they wouldn't. PHP is (to a first approximation) a single
>> implementation language, and so the source code for that implementation
>> is the final reference manual. That's how it is possible to be sure
>> that, at the moment, you can't use ',' as an operator in a general
>> expression. You can scan the grammar to see all the places where a
>> comma is permitted and (pretty much) exactly what it does in all those
>> cases.
>
> There is at least one other important implementation of PHP, namely
> HHVM[1], so I wouldn't call PHP a single implementation language. IMHO
> it would be wise to specify the language formally, before
> implementations may drift apart.
>
> [1] <http://www.hhvm.com/blog/>
Interesting, thanks. I was not aware of any other implementations.
From reading a bit of the site, it seems that the objective is full
agreement with the Zend implementation, so, for the moment, there is
still a single implementation that is the ultimate reference. Any
disagreement in results will be seen as a bug for now (and quite a few
such bugs are listed).
--
Ben.
|
|
|
Re: Object constructors/destructors [message #185090 is a reply to message #185085] |
Tue, 25 February 2014 23:22 |
Adam Harvey
Messages: 25 Registered: September 2010
Karma: 0
|
Junior Member |
|
|
On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>> I firmly believe that it wouldn't make sense to call a (user-defined)
>> constructor when unserializing or cloning an object. A constructor
>> usually serves to initialize an object -- what already had happened in
>> both cases.
>>
>>
> It makes perfect sense. Not everything is necessarily valid in the new
> object. For instance, a logging object may require opening the log
> file. There are many instances where a resource is no longer available
> and needs to be recreated.
Indeed, which is why PHP provides the Serializable interface (and, for BC
reasons, also __sleep and __wakeup) to allow those sorts of
reinitialisation tasks.
I agree with Christoph: since the object is already instantiated, it
doesn't logically make sense to call the constructor once again.
>> Jerry Stuckle wrote:
>>> I know of no other OO language which would allow this.
>>
>> Others may.
>>
>>
> None that I know of. Please name one.
Python's pickle operates the same way:
http://docs.python.org/2/library/pickle.html#object.__getinitargs__
Providing a way to instantiate objects without calling the constructor
does have valid uses (mostly for testing), which is why PHP 5.4 and later
versions also provide a way to do so via reflection (avoiding the
unserialize() hack):
http://php.net/reflectionclass.newinstancewithoutconstructor
Adam
|
|
|
Re: Object constructors/destructors [message #185092 is a reply to message #185085] |
Tue, 25 February 2014 23:18 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> >> Jerry Stuckle wrote:
>>>> >>
>>>> >>> I have my own problems with PHP - for instance, it is entirely
>>>> >>> possible
>>>> >>> to create an object without calling a constructor - a violation
>>>> >>> of OO
>>>> >>> principles. But I work around it.
>>>> >>
>>>> >> How is it possible to create an object without its constructor (if
>>>> >> defined) being called?
>>>> >>
>>>> >
>>>> > Load the object from the $_SESSION. The constructor will not be
>>>> > called.
>>>> >
>>>> > However, the constructor is called when the original object was
>>>> > created,
>>>> > and the destructor called when the original object goes out of scope.
>>>> > The destructor is also called when the object loaded from the
>>>> > $_SESSION
>>>> > goes out of scope.
>>>> >
>>>> > The result is one constructor call and two destructor calls. A
>>>> > violation of OO principles.
>>>>
>>>> Um, I'm not sure whether this is a violation of OOP principles.
>>>> Storing
>>>> an object in the session requires serialization of the object, what is
>>>> somewhat comparable to cloning an object. So actually, you're not
>>>> working with the *same* object.
>>>>
>>>> Anyway, you can work around these issues by using the magic methods
>>>> __sleep() and __wakeup(), as you probably know. :)
>>>>
>>>
>>> Yes, it is a violation. When the script starts, the object is
>>> serialized in the $_SESSION. But it does not exist in the script.
>>> Creating it requires a constructor call.
>>
>> It requires the object to be created in memory somehow, but the defined
>> constructor function is not called in this case.
>>
>
> Which is a violation of OO principles.
>
>>> OO principles require exactly
>>> one constructor call and one destructor call for every object created.
>>> Note these may be explicit or implicit, and the functions may be noops,
>>> but the calls must still be made.
>>
>> When you're cloning an object, its constructor will not be called either.
>>
>
> It is in every other language. For instance, in Java, clone() acts like
> a copy constructor. C++ doesn't have a clone() method, but it does have
> a copy constructor.
Isn't the copy constructor called on other occassions as the normal
constructor?
If so, then PHP doesn't handle that too different. While
__constructor() would be the counterpart of a normal constructor,
__clone() would be the counterpart of a copy constructor.
>>> That is not the case here; you get
>>> one constructor call and two destructor calls.
>>
>> I firmly believe that it wouldn't make sense to call a (user-defined)
>> constructor when unserializing or cloning an object. A constructor
>> usually serves to initialize an object -- what already had happened in
>> both cases.
>>
>
> It makes perfect sense. Not everything is necessarily valid in the new
> object. For instance, a logging object may require opening the log
> file. There are many instances where a resource is no longer available
> and needs to be recreated.
Therefore there are __sleep() and wakeup(). In __sleep() you can close
the log file (if it's still open), and in __wakeup() you can open it again.
Anyway, consider the following snippet:
<?php
class Foo {
function __construct() {
$this->bar = 'foo';
}
function setBar($bar) {
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->setBar('bar');
$bar = unserialize(serialize($foo));
echo $bar->bar;
What output would you expect?
> PHP's method is only a shallow copy. Copy constructors and the like
> were created when a deep copy is required (quite often in other languages).
You can force a deep copy yourself by respectively defining __clone().
>>> I know of no other OO language which would allow this.
>>
>> Others may.
>>
>
> None that I know of. Please name one.
Obviously, I was too terse here. I meant: "I can't name one, but others
may be able to name one."
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185093 is a reply to message #185092] |
Wed, 26 February 2014 02:08 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/25/2014 6:18 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> >>> Jerry Stuckle wrote:
>>>> >>>
>>>> >>>> I have my own problems with PHP - for instance, it is entirely
>>>> >>>> possible
>>>> >>>> to create an object without calling a constructor - a violation
>>>> >>>> of OO
>>>> >>>> principles. But I work around it.
>>>> >>>
>>>> >>> How is it possible to create an object without its constructor (if
>>>> >>> defined) being called?
>>>> >>>
>>>> >>
>>>> >> Load the object from the $_SESSION. The constructor will not be
>>>> >> called.
>>>> >>
>>>> >> However, the constructor is called when the original object was
>>>> >> created,
>>>> >> and the destructor called when the original object goes out of scope.
>>>> >> The destructor is also called when the object loaded from the
>>>> >> $_SESSION
>>>> >> goes out of scope.
>>>> >>
>>>> >> The result is one constructor call and two destructor calls. A
>>>> >> violation of OO principles.
>>>> >
>>>> > Um, I'm not sure whether this is a violation of OOP principles.
>>>> > Storing
>>>> > an object in the session requires serialization of the object, what is
>>>> > somewhat comparable to cloning an object. So actually, you're not
>>>> > working with the *same* object.
>>>> >
>>>> > Anyway, you can work around these issues by using the magic methods
>>>> > __sleep() and __wakeup(), as you probably know. :)
>>>> >
>>>>
>>>> Yes, it is a violation. When the script starts, the object is
>>>> serialized in the $_SESSION. But it does not exist in the script.
>>>> Creating it requires a constructor call.
>>>
>>> It requires the object to be created in memory somehow, but the defined
>>> constructor function is not called in this case.
>>>
>>
>> Which is a violation of OO principles.
>>
>>>> OO principles require exactly
>>>> one constructor call and one destructor call for every object created.
>>>> Note these may be explicit or implicit, and the functions may be noops,
>>>> but the calls must still be made.
>>>
>>> When you're cloning an object, its constructor will not be called either.
>>>
>>
>> It is in every other language. For instance, in Java, clone() acts like
>> a copy constructor. C++ doesn't have a clone() method, but it does have
>> a copy constructor.
>
> Isn't the copy constructor called on other occassions as the normal
> constructor?
>
A copy constructor is a constructor. It can be called, or another one
can be called.
> If so, then PHP doesn't handle that too different. While
> __constructor() would be the counterpart of a normal constructor,
> __clone() would be the counterpart of a copy constructor.
>
__clone() is not called, either.
>>>> That is not the case here; you get
>>>> one constructor call and two destructor calls.
>>>
>>> I firmly believe that it wouldn't make sense to call a (user-defined)
>>> constructor when unserializing or cloning an object. A constructor
>>> usually serves to initialize an object -- what already had happened in
>>> both cases.
>>>
>>
>> It makes perfect sense. Not everything is necessarily valid in the new
>> object. For instance, a logging object may require opening the log
>> file. There are many instances where a resource is no longer available
>> and needs to be recreated.
>
> Therefore there are __sleep() and wakeup(). In __sleep() you can close
> the log file (if it's still open), and in __wakeup() you can open it again.
>
Which have nothing to do with construction/destruction.
> Anyway, consider the following snippet:
>
> <?php
>
> class Foo {
> function __construct() {
> $this->bar = 'foo';
> }
> function setBar($bar) {
> $this->bar = $bar;
> }
> }
>
> $foo = new Foo();
> $foo->setBar('bar');
> $bar = unserialize(serialize($foo));
> echo $bar->bar;
>
> What output would you expect?
>
$bar is a new Foo object, so I would expect a constructor for class Foo
to be called for object $bar. That is how it would work in any true OO
language.
>> PHP's method is only a shallow copy. Copy constructors and the like
>> were created when a deep copy is required (quite often in other languages).
>
> You can force a deep copy yourself by respectively defining __clone().
>
__clone() is not called when initializing from a $_SESSION value.
>>>> I know of no other OO language which would allow this.
>>>
>>> Others may.
>>>
>>
>> None that I know of. Please name one.
>
> Obviously, I was too terse here. I meant: "I can't name one, but others
> may be able to name one."
>
You can't name one because true OO languages do it right.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185094 is a reply to message #185090] |
Wed, 26 February 2014 02:10 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/25/2014 6:22 PM, Adam Harvey wrote:
> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>> I firmly believe that it wouldn't make sense to call a (user-defined)
>>> constructor when unserializing or cloning an object. A constructor
>>> usually serves to initialize an object -- what already had happened in
>>> both cases.
>>>
>>>
>> It makes perfect sense. Not everything is necessarily valid in the new
>> object. For instance, a logging object may require opening the log
>> file. There are many instances where a resource is no longer available
>> and needs to be recreated.
>
> Indeed, which is why PHP provides the Serializable interface (and, for BC
> reasons, also __sleep and __wakeup) to allow those sorts of
> reinitialisation tasks.
>
> I agree with Christoph: since the object is already instantiated, it
> doesn't logically make sense to call the constructor once again.
>
But the object is NOT instantiated. It was at one time, then destroyed.
When the new script starts, there is no object in existence.
>>> Jerry Stuckle wrote:
>>>> I know of no other OO language which would allow this.
>>>
>>> Others may.
>>>
>>>
>> None that I know of. Please name one.
>
> Python's pickle operates the same way:
> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>
> Providing a way to instantiate objects without calling the constructor
> does have valid uses (mostly for testing), which is why PHP 5.4 and later
> versions also provide a way to do so via reflection (avoiding the
> unserialize() hack):
> http://php.net/reflectionclass.newinstancewithoutconstructor
>
> Adam
>
Not knowing Python, I can't say. But if it is a true object, then they
are also violating OO principles.
OO demands creation of a new object requires a constructor call.
Period. If you think otherwise, I suggest you learn more about how OO
is supposed to work. PHP is not a good example.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185096 is a reply to message #185081] |
Wed, 26 February 2014 12:50 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 2/25/14, 4:32 PM, Jerry Stuckle wrote:
> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > I have my own problems with PHP - for instance, it is entirely
>>>> > possible
>>>> > to create an object without calling a constructor - a violation of OO
>>>> > principles. But I work around it.
>>>>
>>>> How is it possible to create an object without its constructor (if
>>>> defined) being called?
>>>>
>>>
>>> Load the object from the $_SESSION. The constructor will not be called.
>>>
>>> However, the constructor is called when the original object was created,
>>> and the destructor called when the original object goes out of scope.
>>> The destructor is also called when the object loaded from the $_SESSION
>>> goes out of scope.
>>>
>>> The result is one constructor call and two destructor calls. A
>>> violation of OO principles.
>>
>> Um, I'm not sure whether this is a violation of OOP principles. Storing
>> an object in the session requires serialization of the object, what is
>> somewhat comparable to cloning an object. So actually, you're not
>> working with the *same* object.
>>
>> Anyway, you can work around these issues by using the magic methods
>> __sleep() and __wakeup(), as you probably know. :)
>>
>
> Yes, it is a violation. When the script starts, the object is
> serialized in the $_SESSION. But it does not exist in the script.
> Creating it requires a constructor call. OO principles require exactly
> one constructor call and one destructor call for every object created.
> Note these may be explicit or implicit, and the functions may be noops,
> but the calls must still be made. That is not the case here; you get
> one constructor call and two destructor calls.
>
> I know of no other OO language which would allow this.
>
An the "name" of the Deserializing constructor in PHP is __wakeup().
You also do NOT get two destructor calls on the same object, the
deserializing created a new object.
|
|
|
Re: Object constructors/destructors [message #185097 is a reply to message #185096] |
Wed, 26 February 2014 13:44 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 7:50 AM, Richard Damon wrote:
> On 2/25/14, 4:32 PM, Jerry Stuckle wrote:
>> On 2/25/2014 4:19 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/25/2014 2:19 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> I have my own problems with PHP - for instance, it is entirely
>>>> >> possible
>>>> >> to create an object without calling a constructor - a violation of OO
>>>> >> principles. But I work around it.
>>>> >
>>>> > How is it possible to create an object without its constructor (if
>>>> > defined) being called?
>>>> >
>>>>
>>>> Load the object from the $_SESSION. The constructor will not be called.
>>>>
>>>> However, the constructor is called when the original object was created,
>>>> and the destructor called when the original object goes out of scope.
>>>> The destructor is also called when the object loaded from the $_SESSION
>>>> goes out of scope.
>>>>
>>>> The result is one constructor call and two destructor calls. A
>>>> violation of OO principles.
>>>
>>> Um, I'm not sure whether this is a violation of OOP principles. Storing
>>> an object in the session requires serialization of the object, what is
>>> somewhat comparable to cloning an object. So actually, you're not
>>> working with the *same* object.
>>>
>>> Anyway, you can work around these issues by using the magic methods
>>> __sleep() and __wakeup(), as you probably know. :)
>>>
>>
>> Yes, it is a violation. When the script starts, the object is
>> serialized in the $_SESSION. But it does not exist in the script.
>> Creating it requires a constructor call. OO principles require exactly
>> one constructor call and one destructor call for every object created.
>> Note these may be explicit or implicit, and the functions may be noops,
>> but the calls must still be made. That is not the case here; you get
>> one constructor call and two destructor calls.
>>
>> I know of no other OO language which would allow this.
>>
>
> An the "name" of the Deserializing constructor in PHP is __wakeup().
>
> You also do NOT get two destructor calls on the same object, the
> deserializing created a new object.
>
__wakeup() is not a constructor - and does not do the same thing.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185105 is a reply to message #185094] |
Wed, 26 February 2014 20:10 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> I firmly believe that it wouldn't make sense to call a (user-defined)
>>>> constructor when unserializing or cloning an object. A constructor
>>>> usually serves to initialize an object -- what already had happened in
>>>> both cases.
>>>>
>>>>
>>> It makes perfect sense. Not everything is necessarily valid in the new
>>> object. For instance, a logging object may require opening the log
>>> file. There are many instances where a resource is no longer available
>>> and needs to be recreated.
>>
>> Indeed, which is why PHP provides the Serializable interface (and, for BC
>> reasons, also __sleep and __wakeup) to allow those sorts of
>> reinitialisation tasks.
>>
>> I agree with Christoph: since the object is already instantiated, it
>> doesn't logically make sense to call the constructor once again.
>>
>
> But the object is NOT instantiated. It was at one time, then destroyed.
> When the new script starts, there is no object in existence.
>
>>>> Jerry Stuckle wrote:
>>>> > I know of no other OO language which would allow this.
>>>>
>>>> Others may.
>>>>
>>>>
>>> None that I know of. Please name one.
>>
>> Python's pickle operates the same way:
>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>
>> Providing a way to instantiate objects without calling the constructor
>> does have valid uses (mostly for testing), which is why PHP 5.4 and later
>> versions also provide a way to do so via reflection (avoiding the
>> unserialize() hack):
>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>
>> Adam
>>
>
> Not knowing Python, I can't say. But if it is a true object, then they
> are also violating OO principles.
>
> OO demands creation of a new object requires a constructor call.
> Period.
Do you understand, what's the purpose of a constructor? It is there to
*initialize* an instance. If there is nothing to initialize, it is not
strictly necessary to call any constructor.
But anyway, unserializing an object is *not* creating a new object.
Consider a class man. When a new object is instantiated the constructor
is called to initialize the person with respective properties (e.g. age
= 0). Later this man goes to sleep (serialize); after he wakes up
(unserialize) the constructor is not called again, as this would reset
the man to his initial properties, and surely after a good night of
sleep one may feel younger, but the age has not been reset.
> If you think otherwise, I suggest you learn more about how OO
> is supposed to work. PHP is not a good example.
I refrain from commenting this statement.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185106 is a reply to message #185105] |
Wed, 26 February 2014 21:01 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> > I firmly believe that it wouldn't make sense to call a (user-defined)
>>>> > constructor when unserializing or cloning an object. A constructor
>>>> > usually serves to initialize an object -- what already had happened in
>>>> > both cases.
>>>> >
>>>> >
>>>> It makes perfect sense. Not everything is necessarily valid in the new
>>>> object. For instance, a logging object may require opening the log
>>>> file. There are many instances where a resource is no longer available
>>>> and needs to be recreated.
>>>
>>> Indeed, which is why PHP provides the Serializable interface (and, for BC
>>> reasons, also __sleep and __wakeup) to allow those sorts of
>>> reinitialisation tasks.
>>>
>>> I agree with Christoph: since the object is already instantiated, it
>>> doesn't logically make sense to call the constructor once again.
>>>
>>
>> But the object is NOT instantiated. It was at one time, then destroyed.
>> When the new script starts, there is no object in existence.
>>
>>>> > Jerry Stuckle wrote:
>>>> >> I know of no other OO language which would allow this.
>>>> >
>>>> > Others may.
>>>> >
>>>> >
>>>> None that I know of. Please name one.
>>>
>>> Python's pickle operates the same way:
>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>
>>> Providing a way to instantiate objects without calling the constructor
>>> does have valid uses (mostly for testing), which is why PHP 5.4 and later
>>> versions also provide a way to do so via reflection (avoiding the
>>> unserialize() hack):
>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>
>>> Adam
>>>
>>
>> Not knowing Python, I can't say. But if it is a true object, then they
>> are also violating OO principles.
>>
>> OO demands creation of a new object requires a constructor call.
>> Period.
>
> Do you understand, what's the purpose of a constructor? It is there to
> *initialize* an instance. If there is nothing to initialize, it is not
> strictly necessary to call any constructor.
>
Yes, I understand the purpose of a constructor - it looks like much more
than you do.
> But anyway, unserializing an object is *not* creating a new object.
> Consider a class man. When a new object is instantiated the constructor
> is called to initialize the person with respective properties (e.g. age
> = 0). Later this man goes to sleep (serialize); after he wakes up
> (unserialize) the constructor is not called again, as this would reset
> the man to his initial properties, and surely after a good night of
> sleep one may feel younger, but the age has not been reset.
>
It is creating a new object. Before unserialize(), the object does not
exist - only a bunch of data. And that data is NOT an object! You
cannot call an object method on the data, for instance. It is no
different than if the data were stored in a file and loaded in Java or
C++, for instance. To create the object requires a call to a constructor.
>> If you think otherwise, I suggest you learn more about how OO
>> is supposed to work. PHP is not a good example.
>
> I refrain from commenting this statement.
>
If you think otherwise, I suggest you learn more about how OO is
supposed to work. PHP is not a good example.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185110 is a reply to message #185106] |
Wed, 26 February 2014 21:59 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> > On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >> I firmly believe that it wouldn't make sense to call a (user-defined)
>>>> >> constructor when unserializing or cloning an object. A constructor
>>>> >> usually serves to initialize an object -- what already had
>>>> >> happened in
>>>> >> both cases.
>>>> >>
>>>> >>
>>>> > It makes perfect sense. Not everything is necessarily valid in the
>>>> > new
>>>> > object. For instance, a logging object may require opening the log
>>>> > file. There are many instances where a resource is no longer
>>>> > available
>>>> > and needs to be recreated.
>>>>
>>>> Indeed, which is why PHP provides the Serializable interface (and,
>>>> for BC
>>>> reasons, also __sleep and __wakeup) to allow those sorts of
>>>> reinitialisation tasks.
>>>>
>>>> I agree with Christoph: since the object is already instantiated, it
>>>> doesn't logically make sense to call the constructor once again.
>>>>
>>>
>>> But the object is NOT instantiated. It was at one time, then destroyed.
>>> When the new script starts, there is no object in existence.
>>>
>>>> >> Jerry Stuckle wrote:
>>>> >>> I know of no other OO language which would allow this.
>>>> >>
>>>> >> Others may.
>>>> >>
>>>> >>
>>>> > None that I know of. Please name one.
>>>>
>>>> Python's pickle operates the same way:
>>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>>
>>>> Providing a way to instantiate objects without calling the constructor
>>>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> later
>>>> versions also provide a way to do so via reflection (avoiding the
>>>> unserialize() hack):
>>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>>
>>>> Adam
>>>>
>>>
>>> Not knowing Python, I can't say. But if it is a true object, then they
>>> are also violating OO principles.
>>>
>>> OO demands creation of a new object requires a constructor call.
>>> Period.
>>
>> Do you understand, what's the purpose of a constructor? It is there to
>> *initialize* an instance. If there is nothing to initialize, it is not
>> strictly necessary to call any constructor.
>>
>
> Yes, I understand the purpose of a constructor - it looks like much more
> than you do.
>
>> But anyway, unserializing an object is *not* creating a new object.
>> Consider a class man. When a new object is instantiated the constructor
>> is called to initialize the person with respective properties (e.g. age
>> = 0). Later this man goes to sleep (serialize); after he wakes up
>> (unserialize) the constructor is not called again, as this would reset
>> the man to his initial properties, and surely after a good night of
>> sleep one may feel younger, but the age has not been reset.
>>
>
> It is creating a new object. Before unserialize(), the object does not
> exist - only a bunch of data. And that data is NOT an object! You
> cannot call an object method on the data, for instance. It is no
> different than if the data were stored in a file and loaded in Java or
> C++, for instance. To create the object requires a call to a constructor.
If you really need to think this way, just take
Serializable::serialize() resp. __sleep() as a destructor and
Serializable::unserialize() resp. __wakeup() as a constructor.
Actually, the documentation of the Serializable interface explaines it
that way.
>>> If you think otherwise, I suggest you learn more about how OO
>>> is supposed to work. PHP is not a good example.
>>
>> I refrain from commenting this statement.
>>
>
> If you think otherwise, I suggest you learn more about how OO is
> supposed to work. PHP is not a good example.
No comment.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185111 is a reply to message #185110] |
Wed, 26 February 2014 22:19 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 4:59 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> > On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>> I firmly believe that it wouldn't make sense to call a (user-defined)
>>>> >>> constructor when unserializing or cloning an object. A constructor
>>>> >>> usually serves to initialize an object -- what already had
>>>> >>> happened in
>>>> >>> both cases.
>>>> >>>
>>>> >>>
>>>> >> It makes perfect sense. Not everything is necessarily valid in the
>>>> >> new
>>>> >> object. For instance, a logging object may require opening the log
>>>> >> file. There are many instances where a resource is no longer
>>>> >> available
>>>> >> and needs to be recreated.
>>>> >
>>>> > Indeed, which is why PHP provides the Serializable interface (and,
>>>> > for BC
>>>> > reasons, also __sleep and __wakeup) to allow those sorts of
>>>> > reinitialisation tasks.
>>>> >
>>>> > I agree with Christoph: since the object is already instantiated, it
>>>> > doesn't logically make sense to call the constructor once again.
>>>> >
>>>>
>>>> But the object is NOT instantiated. It was at one time, then destroyed.
>>>> When the new script starts, there is no object in existence.
>>>>
>>>> >>> Jerry Stuckle wrote:
>>>> >>>> I know of no other OO language which would allow this.
>>>> >>>
>>>> >>> Others may.
>>>> >>>
>>>> >>>
>>>> >> None that I know of. Please name one.
>>>> >
>>>> > Python's pickle operates the same way:
>>>> > http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >
>>>> > Providing a way to instantiate objects without calling the constructor
>>>> > does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> > later
>>>> > versions also provide a way to do so via reflection (avoiding the
>>>> > unserialize() hack):
>>>> > http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >
>>>> > Adam
>>>> >
>>>>
>>>> Not knowing Python, I can't say. But if it is a true object, then they
>>>> are also violating OO principles.
>>>>
>>>> OO demands creation of a new object requires a constructor call.
>>>> Period.
>>>
>>> Do you understand, what's the purpose of a constructor? It is there to
>>> *initialize* an instance. If there is nothing to initialize, it is not
>>> strictly necessary to call any constructor.
>>>
>>
>> Yes, I understand the purpose of a constructor - it looks like much more
>> than you do.
>>
>>> But anyway, unserializing an object is *not* creating a new object.
>>> Consider a class man. When a new object is instantiated the constructor
>>> is called to initialize the person with respective properties (e.g. age
>>> = 0). Later this man goes to sleep (serialize); after he wakes up
>>> (unserialize) the constructor is not called again, as this would reset
>>> the man to his initial properties, and surely after a good night of
>>> sleep one may feel younger, but the age has not been reset.
>>>
>>
>> It is creating a new object. Before unserialize(), the object does not
>> exist - only a bunch of data. And that data is NOT an object! You
>> cannot call an object method on the data, for instance. It is no
>> different than if the data were stored in a file and loaded in Java or
>> C++, for instance. To create the object requires a call to a constructor.
>
> If you really need to think this way, just take
> Serializable::serialize() resp. __sleep() as a destructor and
> Serializable::unserialize() resp. __wakeup() as a constructor.
> Actually, the documentation of the Serializable interface explaines it
> that way.
>
Then it is wrong in another respect, because the destructor is called
after __sleep(), when the object goes out of scope.
>>>> If you think otherwise, I suggest you learn more about how OO
>>>> is supposed to work. PHP is not a good example.
>>>
>>> I refrain from commenting this statement.
>>>
>>
>> If you think otherwise, I suggest you learn more about how OO is
>> supposed to work. PHP is not a good example.
>
> No comment.
>
No matter how you look at it, PHP's implementation violates OO
principles and works differently than any other OO language.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185113 is a reply to message #185111] |
Wed, 26 February 2014 22:39 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/26/2014 4:59 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> >> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>>> I firmly believe that it wouldn't make sense to call a
>>>> >>>> (user-defined)
>>>> >>>> constructor when unserializing or cloning an object. A constructor
>>>> >>>> usually serves to initialize an object -- what already had
>>>> >>>> happened in
>>>> >>>> both cases.
>>>> >>>>
>>>> >>>>
>>>> >>> It makes perfect sense. Not everything is necessarily valid in the
>>>> >>> new
>>>> >>> object. For instance, a logging object may require opening the log
>>>> >>> file. There are many instances where a resource is no longer
>>>> >>> available
>>>> >>> and needs to be recreated.
>>>> >>
>>>> >> Indeed, which is why PHP provides the Serializable interface (and,
>>>> >> for BC
>>>> >> reasons, also __sleep and __wakeup) to allow those sorts of
>>>> >> reinitialisation tasks.
>>>> >>
>>>> >> I agree with Christoph: since the object is already instantiated, it
>>>> >> doesn't logically make sense to call the constructor once again.
>>>> >>
>>>> >
>>>> > But the object is NOT instantiated. It was at one time, then
>>>> > destroyed.
>>>> > When the new script starts, there is no object in existence.
>>>> >
>>>> >>>> Jerry Stuckle wrote:
>>>> >>>>> I know of no other OO language which would allow this.
>>>> >>>>
>>>> >>>> Others may.
>>>> >>>>
>>>> >>>>
>>>> >>> None that I know of. Please name one.
>>>> >>
>>>> >> Python's pickle operates the same way:
>>>> >> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >>
>>>> >> Providing a way to instantiate objects without calling the
>>>> >> constructor
>>>> >> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> >> later
>>>> >> versions also provide a way to do so via reflection (avoiding the
>>>> >> unserialize() hack):
>>>> >> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >>
>>>> >> Adam
>>>> >>
>>>> >
>>>> > Not knowing Python, I can't say. But if it is a true object, then
>>>> > they
>>>> > are also violating OO principles.
>>>> >
>>>> > OO demands creation of a new object requires a constructor call.
>>>> > Period.
>>>>
>>>> Do you understand, what's the purpose of a constructor? It is there to
>>>> *initialize* an instance. If there is nothing to initialize, it is not
>>>> strictly necessary to call any constructor.
>>>>
>>>
>>> Yes, I understand the purpose of a constructor - it looks like much more
>>> than you do.
>>>
>>>> But anyway, unserializing an object is *not* creating a new object.
>>>> Consider a class man. When a new object is instantiated the
>>>> constructor
>>>> is called to initialize the person with respective properties (e.g. age
>>>> = 0). Later this man goes to sleep (serialize); after he wakes up
>>>> (unserialize) the constructor is not called again, as this would reset
>>>> the man to his initial properties, and surely after a good night of
>>>> sleep one may feel younger, but the age has not been reset.
>>>>
>>>
>>> It is creating a new object. Before unserialize(), the object does not
>>> exist - only a bunch of data. And that data is NOT an object! You
>>> cannot call an object method on the data, for instance. It is no
>>> different than if the data were stored in a file and loaded in Java or
>>> C++, for instance. To create the object requires a call to a
>>> constructor.
>>
>> If you really need to think this way, just take
>> Serializable::serialize() resp. __sleep() as a destructor and
>> Serializable::unserialize() resp. __wakeup() as a constructor.
>> Actually, the documentation of the Serializable interface explaines it
>> that way.
>>
>
> Then it is wrong in another respect, because the destructor is called
> after __sleep(), when the object goes out of scope.
>
>>>> > If you think otherwise, I suggest you learn more about
>>>> > how OO
>>>> > is supposed to work. PHP is not a good example.
>>>>
>>>> I refrain from commenting this statement.
>>>>
>>>
>>> If you think otherwise, I suggest you learn more about how OO is
>>> supposed to work. PHP is not a good example.
>>
>> No comment.
>>
>
> No matter how you look at it, PHP's implementation violates OO
> principles and works differently than any other OO language.
You have claimed that often enough, but yet you have not brought any
proof.
E.g. what happens in Java if an object that implements the
java.io.Serializable interface is given as argument to
java.io.OutputStream.writeObject()? Is the destructor called?
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185115 is a reply to message #185105] |
Thu, 27 February 2014 00:00 |
Thomas 'PointedEars'
Messages: 701 Registered: October 2010
Karma: 0
|
Senior Member |
|
|
Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >> I know of no other OO language which would allow this.
>>>> >
>>>> > Others may.
>>>> >
>>>> None that I know of. Please name one.
>>>
>>> Python's pickle operates the same way:
>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>
>>> Providing a way to instantiate objects without calling the constructor
>>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>> later versions also provide a way to do so via reflection (avoiding the
>>> unserialize() hack):
>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>
>> Not knowing Python, I can't say. But if it is a true object, then they
>> are also violating OO principles.
>>
>> OO demands creation of a new object requires a constructor call.
>> Period.
>
> Do you understand, what's the purpose of a constructor? It is there to
> *initialize* an instance. If there is nothing to initialize, it is not
> strictly necessary to call any constructor.
A constructor does not need to mean initialization; primarily it means
*instantiation*: creating an object and, optionally, creating a relation
between it and another object (in the general sense) it inherits from.
However, both instantiation and initialization also can be done by a factory
method. Factory is one of the GoF design patterns, and it does not violate
principles of OOP at all (those people *literally* wrote the book on OOP).
A factory is a function, usually (but not necessarily) a static method, that
returns (a reference to) an object.¹
Speaking of Python, ISTM that it has generalized the Factory pattern so that
both the concept of constructor and the keyword “new” become unnecessary (so
that “new” is not a keyword or reserved word at all) there: A class can be
called like a function – e.g., Class() –, which invokes the __init__()
method of the class if defined, for initialization, and passes to it the
parameters passed to the class/constructor call; otherwise it just
instantiates that class, returning a reference to the instance. (However,
initialization of the instance not dependent on parameters of the
instantiation can also be done in the class code itself.)
$ python3
Python 3.3.5rc1 (default, Feb 23 2014, 19:47:14)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> new = 2
>>> class Class(object): pass
....
>>> Class
<class '__main__.Class'>
>>> Class()
<__main__.Class object at 0xb718d04c>
See also <http://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes>
> But anyway, unserializing an object is *not* creating a new object.
IBTD. However, as we will see soon, it is largely irrelevant that
unserializing *necessarily* creates a new object. Because the relation
between an object and the object it inherits from is just data that can
be stored, and later retrieved to restore that relation, much like a
constructor initially does.
The only important thing is that the relevant parts of the code that
serialized the object and that unserialize data to restore the object must
be identical; otherwise the restored state is not functionally
indistinguishable to the original state of the object. (WLOG, that is the
case as the serializing and unserializing code are the same and are running
in the same or at least a compatible environment.)
> Consider a class man. When a new object is instantiated the constructor
> is called to initialize the person with respective properties (e.g. age
> = 0). Later this man goes to sleep (serialize); after he wakes up
> (unserialize) the constructor is not called again, as this would reset
> the man to his initial properties, and surely after a good night of
> sleep one may feel younger, but the age has not been reset.
That is a really good analogy. (Too bad that Jerry did not understand it.)
It points out that, basically, an object is a collection of data, and
methods to operate on/with that data. WLOG, data is serializable, and
methods are inherited from another object (in the general sense; in class-
based OOP: a class). The relation to that other object again is just data.²
Data can be stored in different forms, and retrieved. Therefore, an object
can be restored to its previous state, or at least to a state that is
functionally indistinguishable from its previous state, without calling a
constructor.
$ php -r '
class C implements Serializable
{
private $_data = 42;
function serialize()
{
return serialize($this->_data);
}
function unserialize ($serialized)
{
echo "\$serialized = "; var_dump($serialized);
$this->_data = unserialize($serialized);
}
};
$c = new C();
echo "\$c = "; var_dump($c);
$s = serialize($c);
echo "\$s = "; var_dump($s);
$c = unserialize($s);
echo "\$c = "; var_dump($c);
'
class C#1 (1) {
private $_data =>
int(42)
}
string(17) "C:1:"C":5:{i:42;}"
string(5) "i:42;"
class C#2 (1) {
private $_data =>
int(42)
}
PointedEars
___________
¹ Those who object to considering a mere function OOP should read the
ECMAScript Language Specification, which shows that every function can be
made a method of an object; especially, globally declared functions are
methods of a global object.
² Even if a method is not inherited (which cannot happen in PHP) it would
be possible to serialize it as it is just code. However, this is not
always possible by means of the language itself instead of the core
language implementation.
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7(at)news(dot)demon(dot)co(dot)uk> (2004)
|
|
|
Re: Object constructors/destructors [message #185116 is a reply to message #185113] |
Thu, 27 February 2014 03:30 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/26/2014 4:59 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> >>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>>>> I firmly believe that it wouldn't make sense to call a
>>>> >>>>> (user-defined)
>>>> >>>>> constructor when unserializing or cloning an object. A constructor
>>>> >>>>> usually serves to initialize an object -- what already had
>>>> >>>>> happened in
>>>> >>>>> both cases.
>>>> >>>>>
>>>> >>>>>
>>>> >>>> It makes perfect sense. Not everything is necessarily valid in the
>>>> >>>> new
>>>> >>>> object. For instance, a logging object may require opening the log
>>>> >>>> file. There are many instances where a resource is no longer
>>>> >>>> available
>>>> >>>> and needs to be recreated.
>>>> >>>
>>>> >>> Indeed, which is why PHP provides the Serializable interface (and,
>>>> >>> for BC
>>>> >>> reasons, also __sleep and __wakeup) to allow those sorts of
>>>> >>> reinitialisation tasks.
>>>> >>>
>>>> >>> I agree with Christoph: since the object is already instantiated, it
>>>> >>> doesn't logically make sense to call the constructor once again.
>>>> >>>
>>>> >>
>>>> >> But the object is NOT instantiated. It was at one time, then
>>>> >> destroyed.
>>>> >> When the new script starts, there is no object in existence.
>>>> >>
>>>> >>>>> Jerry Stuckle wrote:
>>>> >>>>>> I know of no other OO language which would allow this.
>>>> >>>>>
>>>> >>>>> Others may.
>>>> >>>>>
>>>> >>>>>
>>>> >>>> None that I know of. Please name one.
>>>> >>>
>>>> >>> Python's pickle operates the same way:
>>>> >>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >>>
>>>> >>> Providing a way to instantiate objects without calling the
>>>> >>> constructor
>>>> >>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> >>> later
>>>> >>> versions also provide a way to do so via reflection (avoiding the
>>>> >>> unserialize() hack):
>>>> >>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >>>
>>>> >>> Adam
>>>> >>>
>>>> >>
>>>> >> Not knowing Python, I can't say. But if it is a true object, then
>>>> >> they
>>>> >> are also violating OO principles.
>>>> >>
>>>> >> OO demands creation of a new object requires a constructor call.
>>>> >> Period.
>>>> >
>>>> > Do you understand, what's the purpose of a constructor? It is there to
>>>> > *initialize* an instance. If there is nothing to initialize, it is not
>>>> > strictly necessary to call any constructor.
>>>> >
>>>>
>>>> Yes, I understand the purpose of a constructor - it looks like much more
>>>> than you do.
>>>>
>>>> > But anyway, unserializing an object is *not* creating a new object.
>>>> > Consider a class man. When a new object is instantiated the
>>>> > constructor
>>>> > is called to initialize the person with respective properties (e.g. age
>>>> > = 0). Later this man goes to sleep (serialize); after he wakes up
>>>> > (unserialize) the constructor is not called again, as this would reset
>>>> > the man to his initial properties, and surely after a good night of
>>>> > sleep one may feel younger, but the age has not been reset.
>>>> >
>>>>
>>>> It is creating a new object. Before unserialize(), the object does not
>>>> exist - only a bunch of data. And that data is NOT an object! You
>>>> cannot call an object method on the data, for instance. It is no
>>>> different than if the data were stored in a file and loaded in Java or
>>>> C++, for instance. To create the object requires a call to a
>>>> constructor.
>>>
>>> If you really need to think this way, just take
>>> Serializable::serialize() resp. __sleep() as a destructor and
>>> Serializable::unserialize() resp. __wakeup() as a constructor.
>>> Actually, the documentation of the Serializable interface explaines it
>>> that way.
>>>
>>
>> Then it is wrong in another respect, because the destructor is called
>> after __sleep(), when the object goes out of scope.
>>
>>>> >> If you think otherwise, I suggest you learn more about
>>>> >> how OO
>>>> >> is supposed to work. PHP is not a good example.
>>>> >
>>>> > I refrain from commenting this statement.
>>>> >
>>>>
>>>> If you think otherwise, I suggest you learn more about how OO is
>>>> supposed to work. PHP is not a good example.
>>>
>>> No comment.
>>>
>>
>> No matter how you look at it, PHP's implementation violates OO
>> principles and works differently than any other OO language.
>
> You have claimed that often enough, but yet you have not brought any
> proof.
>
> E.g. what happens in Java if an object that implements the
> java.io.Serializable interface is given as argument to
> java.io.OutputStream.writeObject()? Is the destructor called?
>
Yes, it is. But when the new object is created, a constructor is
called. You cannot unserialize an object without a constructor being
called first.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185117 is a reply to message #185115] |
Thu, 27 February 2014 03:39 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 7:00 PM, Thomas 'PointedEars' Lahn wrote:
> Christoph Michael Becker wrote:
>
>> Jerry Stuckle wrote:
>>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> > On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >> Jerry Stuckle wrote:
>>>> >>> I know of no other OO language which would allow this.
>>>> >>
>>>> >> Others may.
>>>> >>
>>>> > None that I know of. Please name one.
>>>>
>>>> Python's pickle operates the same way:
>>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>>
>>>> Providing a way to instantiate objects without calling the constructor
>>>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> later versions also provide a way to do so via reflection (avoiding the
>>>> unserialize() hack):
>>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>
>>> Not knowing Python, I can't say. But if it is a true object, then they
>>> are also violating OO principles.
>>>
>>> OO demands creation of a new object requires a constructor call.
>>> Period.
>>
>> Do you understand, what's the purpose of a constructor? It is there to
>> *initialize* an instance. If there is nothing to initialize, it is not
>> strictly necessary to call any constructor.
>
> A constructor does not need to mean initialization; primarily it means
> *instantiation*: creating an object and, optionally, creating a relation
> between it and another object (in the general sense) it inherits from.
> However, both instantiation and initialization also can be done by a factory
> method. Factory is one of the GoF design patterns, and it does not violate
> principles of OOP at all (those people *literally* wrote the book on OOP).
> A factory is a function, usually (but not necessarily) a static method, that
> returns (a reference to) an object.¹
>
Incorrect (as usual). The constructor is designed to initialize an
object. In OO programming, an object is always valid, or, if not valid,
refuses any operations which depend on the object being valid.
A factory is only a means of instantiating the object. It does not
replace or preclude the constructor being called.
> Speaking of Python, ISTM that it has generalized the Factory pattern so that
> both the concept of constructor and the keyword “new” become unnecessary (so
> that “new” is not a keyword or reserved word at all) there: A class can be
> called like a function – e.g., Class() –, which invokes the __init__()
> method of the class if defined, for initialization, and passes to it the
> parameters passed to the class/constructor call; otherwise it just
> instantiates that class, returning a reference to the instance. (However,
> initialization of the instance not dependent on parameters of the
> instantiation can also be done in the class code itself.)
>
> $ python3
> Python 3.3.5rc1 (default, Feb 23 2014, 19:47:14)
> [GCC 4.8.2] on linux
> Type "help", "copyright", "credits" or "license" for more information.
Which means the constructor IS called.
>>>> new = 2
>>>> class Class(object): pass
> ...
>>>> Class
> <class '__main__.Class'>
>>>> Class()
> <__main__.Class object at 0xb718d04c>
>
> See also <http://docs.python.org/3/tutorial/classes.html#a-first-look-at-classes>
>
>> But anyway, unserializing an object is *not* creating a new object.
>
> IBTD. However, as we will see soon, it is largely irrelevant that
> unserializing *necessarily* creates a new object. Because the relation
> between an object and the object it inherits from is just data that can
> be stored, and later retrieved to restore that relation, much like a
> constructor initially does.
>
It is not at all irrelevant. Unserializing an object by definition
creates a new object.
> The only important thing is that the relevant parts of the code that
> serialized the object and that unserialize data to restore the object must
> be identical; otherwise the restored state is not functionally
> indistinguishable to the original state of the object. (WLOG, that is the
> case as the serializing and unserializing code are the same and are running
> in the same or at least a compatible environment.)
>
But it cannot always be identical. For instance, one of the members of
an object may be a file handle; that file handle is no longer valid and
the file being used must be opened again - creating a new file handle.
>> Consider a class man. When a new object is instantiated the constructor
>> is called to initialize the person with respective properties (e.g. age
>> = 0). Later this man goes to sleep (serialize); after he wakes up
>> (unserialize) the constructor is not called again, as this would reset
>> the man to his initial properties, and surely after a good night of
>> sleep one may feel younger, but the age has not been reset.
>
> That is a really good analogy. (Too bad that Jerry did not understand it.)
> It points out that, basically, an object is a collection of data, and
> methods to operate on/with that data. WLOG, data is serializable, and
> methods are inherited from another object (in the general sense; in class-
> based OOP: a class). The relation to that other object again is just data.²
> Data can be stored in different forms, and retrieved. Therefore, an object
> can be restored to its previous state, or at least to a state that is
> functionally indistinguishable from its previous state, without calling a
> constructor.
>
I understood it, but it is a bad example. Calling a constructor does
NOT necessarily reset the object to an initial state - this happens only
in PHP. In REAL OO languages, the object can be initialized to other
data - a good example is the copy constructor in either C++ or Java.
> $ php -r '
> class C implements Serializable
> {
> private $_data = 42;
>
> function serialize()
> {
> return serialize($this->_data);
> }
>
> function unserialize ($serialized)
> {
> echo "\$serialized = "; var_dump($serialized);
>
> $this->_data = unserialize($serialized);
> }
> };
>
> $c = new C();
>
> echo "\$c = "; var_dump($c);
>
> $s = serialize($c);
>
> echo "\$s = "; var_dump($s);
>
> $c = unserialize($s);
>
> echo "\$c = "; var_dump($c);
> '
> class C#1 (1) {
> private $_data =>
> int(42)
> }
> string(17) "C:1:"C":5:{i:42;}"
> string(5) "i:42;"
> class C#2 (1) {
> private $_data =>
> int(42)
> }
>
>
Which just shows that PHP does not implement OO operations properly.
P.S. Your sig separator is broken. It should be exactly
hyphen-hyphen-space-newline.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185118 is a reply to message #185097] |
Thu, 27 February 2014 04:49 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
> On 2/26/2014 7:50 AM, Richard Damon wrote:
>>
>> An the "name" of the Deserializing constructor in PHP is __wakeup().
>>
>> You also do NOT get two destructor calls on the same object, the
>> deserializing created a new object.
>>
>
> __wakeup() is not a constructor - and does not do the same thing.
>
What makes it NOT a constructor? IT seems to be exactly the thing that
does what you say must be done to make the new object via unserialization.
|
|
|
Re: Object constructors/destructors [message #185121 is a reply to message #185118] |
Thu, 27 February 2014 13:25 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/26/2014 11:49 PM, Richard Damon wrote:
> On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
>> On 2/26/2014 7:50 AM, Richard Damon wrote:
>>>
>>> An the "name" of the Deserializing constructor in PHP is __wakeup().
>>>
>>> You also do NOT get two destructor calls on the same object, the
>>> deserializing created a new object.
>>>
>>
>> __wakeup() is not a constructor - and does not do the same thing.
>>
>
> What makes it NOT a constructor? IT seems to be exactly the thing that
> does what you say must be done to make the new object via unserialization.
>
If you want to consider __wakeup() to be a constructor, then you must
consider __sleep() to be a destructor. In that case, PHP is also wrong
because if an object is serialized, it will call both __sleep() and the
destructor. This would be two calls to destructors for the same object.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185124 is a reply to message #185116] |
Thu, 27 February 2014 17:28 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/26/2014 4:59 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>>>> >> Jerry Stuckle wrote:
>>>> >>
>>>> >>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> >>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >>>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>>>>> I firmly believe that it wouldn't make sense to call a
>>>> >>>>>> (user-defined)
>>>> >>>>>> constructor when unserializing or cloning an object. A
>>>> >>>>>> constructor
>>>> >>>>>> usually serves to initialize an object -- what already had
>>>> >>>>>> happened in
>>>> >>>>>> both cases.
>>>> >>>>>>
>>>> >>>>>>
>>>> >>>>> It makes perfect sense. Not everything is necessarily valid in
>>>> >>>>> the
>>>> >>>>> new
>>>> >>>>> object. For instance, a logging object may require opening the
>>>> >>>>> log
>>>> >>>>> file. There are many instances where a resource is no longer
>>>> >>>>> available
>>>> >>>>> and needs to be recreated.
>>>> >>>>
>>>> >>>> Indeed, which is why PHP provides the Serializable interface (and,
>>>> >>>> for BC
>>>> >>>> reasons, also __sleep and __wakeup) to allow those sorts of
>>>> >>>> reinitialisation tasks.
>>>> >>>>
>>>> >>>> I agree with Christoph: since the object is already
>>>> >>>> instantiated, it
>>>> >>>> doesn't logically make sense to call the constructor once again.
>>>> >>>>
>>>> >>>
>>>> >>> But the object is NOT instantiated. It was at one time, then
>>>> >>> destroyed.
>>>> >>> When the new script starts, there is no object in existence.
>>>> >>>
>>>> >>>>>> Jerry Stuckle wrote:
>>>> >>>>>>> I know of no other OO language which would allow this.
>>>> >>>>>>
>>>> >>>>>> Others may.
>>>> >>>>>>
>>>> >>>>>>
>>>> >>>>> None that I know of. Please name one.
>>>> >>>>
>>>> >>>> Python's pickle operates the same way:
>>>> >>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >>>>
>>>> >>>> Providing a way to instantiate objects without calling the
>>>> >>>> constructor
>>>> >>>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> >>>> later
>>>> >>>> versions also provide a way to do so via reflection (avoiding the
>>>> >>>> unserialize() hack):
>>>> >>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >>>>
>>>> >>>> Adam
>>>> >>>>
>>>> >>>
>>>> >>> Not knowing Python, I can't say. But if it is a true object, then
>>>> >>> they
>>>> >>> are also violating OO principles.
>>>> >>>
>>>> >>> OO demands creation of a new object requires a constructor call.
>>>> >>> Period.
>>>> >>
>>>> >> Do you understand, what's the purpose of a constructor? It is
>>>> >> there to
>>>> >> *initialize* an instance. If there is nothing to initialize, it
>>>> >> is not
>>>> >> strictly necessary to call any constructor.
>>>> >>
>>>> >
>>>> > Yes, I understand the purpose of a constructor - it looks like much
>>>> > more
>>>> > than you do.
>>>> >
>>>> >> But anyway, unserializing an object is *not* creating a new object.
>>>> >> Consider a class man. When a new object is instantiated the
>>>> >> constructor
>>>> >> is called to initialize the person with respective properties
>>>> >> (e.g. age
>>>> >> = 0). Later this man goes to sleep (serialize); after he wakes up
>>>> >> (unserialize) the constructor is not called again, as this would
>>>> >> reset
>>>> >> the man to his initial properties, and surely after a good night of
>>>> >> sleep one may feel younger, but the age has not been reset.
>>>> >>
>>>> >
>>>> > It is creating a new object. Before unserialize(), the object does
>>>> > not
>>>> > exist - only a bunch of data. And that data is NOT an object! You
>>>> > cannot call an object method on the data, for instance. It is no
>>>> > different than if the data were stored in a file and loaded in Java or
>>>> > C++, for instance. To create the object requires a call to a
>>>> > constructor.
>>>>
>>>> If you really need to think this way, just take
>>>> Serializable::serialize() resp. __sleep() as a destructor and
>>>> Serializable::unserialize() resp. __wakeup() as a constructor.
>>>> Actually, the documentation of the Serializable interface explaines it
>>>> that way.
>>>>
>>>
>>> Then it is wrong in another respect, because the destructor is called
>>> after __sleep(), when the object goes out of scope.
>>>
>>>> >>> If you think otherwise, I suggest you learn more about
>>>> >>> how OO
>>>> >>> is supposed to work. PHP is not a good example.
>>>> >>
>>>> >> I refrain from commenting this statement.
>>>> >>
>>>> >
>>>> > If you think otherwise, I suggest you learn more about how OO is
>>>> > supposed to work. PHP is not a good example.
>>>>
>>>> No comment.
>>>>
>>>
>>> No matter how you look at it, PHP's implementation violates OO
>>> principles and works differently than any other OO language.
>>
>> You have claimed that often enough, but yet you have not brought any
>> proof.
>>
>> E.g. what happens in Java if an object that implements the
>> java.io.Serializable interface is given as argument to
>> java.io.OutputStream.writeObject()? Is the destructor called?
>>
>
> Yes, it is.
I strongly doubt that. On one hand this would mean you can't use the
object as soon as it has been written to the stream, and on the other
hand there are no *destructors* in Java (finalize() is similar to a
destructor, but it is not guaranteed that it will be called).
Furthermore it depends on the garbage collector, when an object will be
*destroyed*.
> But when the new object is created, a constructor is
> called. You cannot unserialize an object without a constructor being
> called first.
I doubt that, too. After all, java.io.ObjectInputStream.readObject()
returns an object, which of course has to be *created* -- but there's no
need to call its *constructor*.
However, I believe our dissent mainly stems from different use of terms.
I am accustomed to understand constructor/destructor as user defined
functions (which can be defined for custom initialization/finalization
tasks), while this may not be the common definition.
When you're talking about OO principles wrt. to
construction/destruction, you're most likely referring to RAII, which is
not necessarily a general OO principle, and might not be possible to be
cleanly implemented in garbage collected languages generally (consider
cyclic references).
Anyway, I somewhat consider this discussion as harping on about
principles, and I still don't see that PHP lacks the really important
concepts regarding object (de)serialization and cloning.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185125 is a reply to message #185117] |
Thu, 27 February 2014 17:29 |
Thomas 'PointedEars'
Messages: 701 Registered: October 2010
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/26/2014 7:00 PM, Thomas 'PointedEars' Lahn wrote:
>> Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> > On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>> Jerry Stuckle wrote:
>>>> >>>> I know of no other OO language which would allow this.
>>>> >>> Others may.
>>>> >> None that I know of. Please name one.
>>>> >
>>>> > Python's pickle operates the same way:
>>>> > http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >
>>>> > Providing a way to instantiate objects without calling the constructor
>>>> > does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> > later versions also provide a way to do so via reflection (avoiding
>>>> > the unserialize() hack):
>>>> > http://php.net/reflectionclass.newinstancewithoutconstructor
>>>>
>>>> Not knowing Python, I can't say. But if it is a true object, then they
>>>> are also violating OO principles.
>>>>
>>>> OO demands creation of a new object requires a constructor call.
>>>> Period.
>>>
>>> Do you understand, what's the purpose of a constructor? It is there to
>>> *initialize* an instance. If there is nothing to initialize, it is not
>>> strictly necessary to call any constructor.
>>
>> A constructor does not need to mean initialization; primarily it means
>> *instantiation*: creating an object and, optionally, creating a relation
>> between it and another object (in the general sense) it inherits from.
>> However, both instantiation and initialization also can be done by a
>> factory method. Factory is one of the GoF design patterns, and it does
>> not violate principles of OOP at all (those people *literally* wrote the
>> book on OOP). A factory is a function, usually (but not necessarily) a
>> static method, that returns (a reference to) an object.¹
>
> Incorrect (as usual). The constructor is designed to initialize an
> object. In OO programming, an object is always valid, or, if not valid,
> refuses any operations which depend on the object being valid.
At this point I would refer you to “Design Patterns. Elements of Reusable
Object-Oriented Software” (ISBN 3-8273-2199-9) if I not already knew that
you knew everything that is to know about OOP :->
> A factory is only a means of instantiating the object.
No, it can initialize the object, too. I have already given an example *in
PHP*; you are not paying attention.
> It does not replace or preclude the constructor being called.
Nobody said it would.
> [tl;dr Jerry's further misconceptions]
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
|
|
|
Re: Object constructors/destructors [message #185129 is a reply to message #185124] |
Thu, 27 February 2014 21:09 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/27/2014 12:28 PM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/26/2014 4:59 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> On 2/26/2014 3:10 PM, Christoph Michael Becker wrote:
>>>> >>> Jerry Stuckle wrote:
>>>> >>>
>>>> >>>> On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> >>>>> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >>>>>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>>>>>> I firmly believe that it wouldn't make sense to call a
>>>> >>>>>>> (user-defined)
>>>> >>>>>>> constructor when unserializing or cloning an object. A
>>>> >>>>>>> constructor
>>>> >>>>>>> usually serves to initialize an object -- what already had
>>>> >>>>>>> happened in
>>>> >>>>>>> both cases.
>>>> >>>>>>>
>>>> >>>>>>>
>>>> >>>>>> It makes perfect sense. Not everything is necessarily valid in
>>>> >>>>>> the
>>>> >>>>>> new
>>>> >>>>>> object. For instance, a logging object may require opening the
>>>> >>>>>> log
>>>> >>>>>> file. There are many instances where a resource is no longer
>>>> >>>>>> available
>>>> >>>>>> and needs to be recreated.
>>>> >>>>>
>>>> >>>>> Indeed, which is why PHP provides the Serializable interface (and,
>>>> >>>>> for BC
>>>> >>>>> reasons, also __sleep and __wakeup) to allow those sorts of
>>>> >>>>> reinitialisation tasks.
>>>> >>>>>
>>>> >>>>> I agree with Christoph: since the object is already
>>>> >>>>> instantiated, it
>>>> >>>>> doesn't logically make sense to call the constructor once again.
>>>> >>>>>
>>>> >>>>
>>>> >>>> But the object is NOT instantiated. It was at one time, then
>>>> >>>> destroyed.
>>>> >>>> When the new script starts, there is no object in existence.
>>>> >>>>
>>>> >>>>>>> Jerry Stuckle wrote:
>>>> >>>>>>>> I know of no other OO language which would allow this.
>>>> >>>>>>>
>>>> >>>>>>> Others may.
>>>> >>>>>>>
>>>> >>>>>>>
>>>> >>>>>> None that I know of. Please name one.
>>>> >>>>>
>>>> >>>>> Python's pickle operates the same way:
>>>> >>>>> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >>>>>
>>>> >>>>> Providing a way to instantiate objects without calling the
>>>> >>>>> constructor
>>>> >>>>> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> >>>>> later
>>>> >>>>> versions also provide a way to do so via reflection (avoiding the
>>>> >>>>> unserialize() hack):
>>>> >>>>> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >>>>>
>>>> >>>>> Adam
>>>> >>>>>
>>>> >>>>
>>>> >>>> Not knowing Python, I can't say. But if it is a true object, then
>>>> >>>> they
>>>> >>>> are also violating OO principles.
>>>> >>>>
>>>> >>>> OO demands creation of a new object requires a constructor call.
>>>> >>>> Period.
>>>> >>>
>>>> >>> Do you understand, what's the purpose of a constructor? It is
>>>> >>> there to
>>>> >>> *initialize* an instance. If there is nothing to initialize, it
>>>> >>> is not
>>>> >>> strictly necessary to call any constructor.
>>>> >>>
>>>> >>
>>>> >> Yes, I understand the purpose of a constructor - it looks like much
>>>> >> more
>>>> >> than you do.
>>>> >>
>>>> >>> But anyway, unserializing an object is *not* creating a new object.
>>>> >>> Consider a class man. When a new object is instantiated the
>>>> >>> constructor
>>>> >>> is called to initialize the person with respective properties
>>>> >>> (e.g. age
>>>> >>> = 0). Later this man goes to sleep (serialize); after he wakes up
>>>> >>> (unserialize) the constructor is not called again, as this would
>>>> >>> reset
>>>> >>> the man to his initial properties, and surely after a good night of
>>>> >>> sleep one may feel younger, but the age has not been reset.
>>>> >>>
>>>> >>
>>>> >> It is creating a new object. Before unserialize(), the object does
>>>> >> not
>>>> >> exist - only a bunch of data. And that data is NOT an object! You
>>>> >> cannot call an object method on the data, for instance. It is no
>>>> >> different than if the data were stored in a file and loaded in Java or
>>>> >> C++, for instance. To create the object requires a call to a
>>>> >> constructor.
>>>> >
>>>> > If you really need to think this way, just take
>>>> > Serializable::serialize() resp. __sleep() as a destructor and
>>>> > Serializable::unserialize() resp. __wakeup() as a constructor.
>>>> > Actually, the documentation of the Serializable interface explaines it
>>>> > that way.
>>>> >
>>>>
>>>> Then it is wrong in another respect, because the destructor is called
>>>> after __sleep(), when the object goes out of scope.
>>>>
>>>> >>>> If you think otherwise, I suggest you learn more about
>>>> >>>> how OO
>>>> >>>> is supposed to work. PHP is not a good example.
>>>> >>>
>>>> >>> I refrain from commenting this statement.
>>>> >>>
>>>> >>
>>>> >> If you think otherwise, I suggest you learn more about how OO is
>>>> >> supposed to work. PHP is not a good example.
>>>> >
>>>> > No comment.
>>>> >
>>>>
>>>> No matter how you look at it, PHP's implementation violates OO
>>>> principles and works differently than any other OO language.
>>>
>>> You have claimed that often enough, but yet you have not brought any
>>> proof.
>>>
>>> E.g. what happens in Java if an object that implements the
>>> java.io.Serializable interface is given as argument to
>>> java.io.OutputStream.writeObject()? Is the destructor called?
>>>
>>
>> Yes, it is.
>
> I strongly doubt that. On one hand this would mean you can't use the
> object as soon as it has been written to the stream, and on the other
> hand there are no *destructors* in Java (finalize() is similar to a
> destructor, but it is not guaranteed that it will be called).
> Furthermore it depends on the garbage collector, when an object will be
> *destroyed*.
>
>> But when the new object is created, a constructor is
>> called. You cannot unserialize an object without a constructor being
>> called first.
>
> I doubt that, too. After all, java.io.ObjectInputStream.readObject()
> returns an object, which of course has to be *created* -- but there's no
> need to call its *constructor*.
>
No, because the constructor is called automatically.
> However, I believe our dissent mainly stems from different use of terms.
> I am accustomed to understand constructor/destructor as user defined
> functions (which can be defined for custom initialization/finalization
> tasks), while this may not be the common definition.
>
They may be user defined, or they may be defined by the system (as in
the absence of a user-defined constructor).
> When you're talking about OO principles wrt. to
> construction/destruction, you're most likely referring to RAII, which is
> not necessarily a general OO principle, and might not be possible to be
> cleanly implemented in garbage collected languages generally (consider
> cyclic references).
>
No, I am not referring to RAII. I am referring to basic OO principles.
> Anyway, I somewhat consider this discussion as harping on about
> principles, and I still don't see that PHP lacks the really important
> concepts regarding object (de)serialization and cloning.
>
Just that it doesn't follow OO principles - which has caused me problems
in the past.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185130 is a reply to message #185125] |
Thu, 27 February 2014 21:14 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/27/2014 12:29 PM, Thomas 'PointedEars' Lahn wrote:
> Jerry Stuckle wrote:
>
>> On 2/26/2014 7:00 PM, Thomas 'PointedEars' Lahn wrote:
>>> Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>> > On 2/25/2014 6:22 PM, Adam Harvey wrote:
>>>> >> On Tue, 25 Feb 2014 17:01:52 -0500, Jerry Stuckle wrote:
>>>> >>> On 2/25/2014 4:55 PM, Christoph Michael Becker wrote:
>>>> >>>> Jerry Stuckle wrote:
>>>> >>>>> I know of no other OO language which would allow this.
>>>> >>>> Others may.
>>>> >>> None that I know of. Please name one.
>>>> >>
>>>> >> Python's pickle operates the same way:
>>>> >> http://docs.python.org/2/library/pickle.html#object.__getinitargs__
>>>> >>
>>>> >> Providing a way to instantiate objects without calling the constructor
>>>> >> does have valid uses (mostly for testing), which is why PHP 5.4 and
>>>> >> later versions also provide a way to do so via reflection (avoiding
>>>> >> the unserialize() hack):
>>>> >> http://php.net/reflectionclass.newinstancewithoutconstructor
>>>> >
>>>> > Not knowing Python, I can't say. But if it is a true object, then they
>>>> > are also violating OO principles.
>>>> >
>>>> > OO demands creation of a new object requires a constructor call.
>>>> > Period.
>>>>
>>>> Do you understand, what's the purpose of a constructor? It is there to
>>>> *initialize* an instance. If there is nothing to initialize, it is not
>>>> strictly necessary to call any constructor.
>>>
>>> A constructor does not need to mean initialization; primarily it means
>>> *instantiation*: creating an object and, optionally, creating a relation
>>> between it and another object (in the general sense) it inherits from.
>>> However, both instantiation and initialization also can be done by a
>>> factory method. Factory is one of the GoF design patterns, and it does
>>> not violate principles of OOP at all (those people *literally* wrote the
>>> book on OOP). A factory is a function, usually (but not necessarily) a
>>> static method, that returns (a reference to) an object.¹
>>
>> Incorrect (as usual). The constructor is designed to initialize an
>> object. In OO programming, an object is always valid, or, if not valid,
>> refuses any operations which depend on the object being valid.
>
> At this point I would refer you to “Design Patterns. Elements of Reusable
> Object-Oriented Software” (ISBN 3-8273-2199-9) if I not already knew that
> you knew everything that is to know about OOP :->
>
Which does not contradict my statement.
>> A factory is only a means of instantiating the object.
>
> No, it can initialize the object, too. I have already given an example *in
> PHP*; you are not paying attention.
>
Yes, and in real OO languages, it uses a constructor to do so. It does
not eliminate the need for the constructor(s).
For instance, a factory object cannot directly initialize the private or
protected members of an object (an exception being if it is declared a
"friend" object in C++ - which is frowned upon), nor can it initialize
the private or protected members of a base class.
But then a factory is generally not a static method of an object; rather
it is normally another object.
>> It does not replace or preclude the constructor being called.
>
> Nobody said it would.
>
>> [tl;dr Jerry's further misconceptions]
>
>
> PointedEars
>
Shot down again, Pointed Head.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185134 is a reply to message #185129] |
Fri, 28 February 2014 13:52 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/27/2014 12:28 PM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > No matter how you look at it, PHP's implementation violates OO
>>>> > principles and works differently than any other OO language.
>>>>
>>>> You have claimed that often enough, but yet you have not brought any
>>>> proof.
>>>>
>>>> E.g. what happens in Java if an object that implements the
>>>> java.io.Serializable interface is given as argument to
>>>> java.io.OutputStream.writeObject()? Is the destructor called?
>>>>
>>>
>>> Yes, it is.
>>
>> I strongly doubt that. On one hand this would mean you can't use the
>> object as soon as it has been written to the stream, and on the other
>> hand there are no *destructors* in Java (finalize() is similar to a
>> destructor, but it is not guaranteed that it will be called).
>> Furthermore it depends on the garbage collector, when an object will be
>> *destroyed*.
>>
>>> But when the new object is created, a constructor is
>>> called. You cannot unserialize an object without a constructor being
>>> called first.
>>
>> I doubt that, too. After all, java.io.ObjectInputStream.readObject()
>> returns an object, which of course has to be *created* -- but there's no
>> need to call its *constructor*.
>>
>
> No, because the constructor is called automatically.
Wrong, see below.
>> However, I believe our dissent mainly stems from different use of terms.
>> I am accustomed to understand constructor/destructor as user defined
>> functions (which can be defined for custom initialization/finalization
>> tasks), while this may not be the common definition.
>>
>
> They may be user defined, or they may be defined by the system (as in
> the absence of a user-defined constructor).
>
>> When you're talking about OO principles wrt. to
>> construction/destruction, you're most likely referring to RAII, which is
>> not necessarily a general OO principle, and might not be possible to be
>> cleanly implemented in garbage collected languages generally (consider
>> cyclic references).
>>
>
> No, I am not referring to RAII. I am referring to basic OO principles.
>
>> Anyway, I somewhat consider this discussion as harping on about
>> principles, and I still don't see that PHP lacks the really important
>> concepts regarding object (de)serialization and cloning.
>>
>
> Just that it doesn't follow OO principles - which has caused me problems
> in the past.
To shorten further discussion I have installed the JDK 7u51, and written
the following classes:
---- Foo.java ----
public class Foo implements java.io.Serializable {
protected int bar;
public Foo() {
System.out.println("Constructor of Foo called");
bar = 0;
}
public int getBar() {
return bar;
}
public void setBar(int value) {
bar = value;
}
}
---- Demo.java ----
import java.io.*;
public class Demo {
public static void main(String[] args)
throws IOException, ClassNotFoundException {
Foo foo = new Foo();
foo.setBar(42);
FileOutputStream fileOut = new FileOutputStream("./ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(foo);
out.close();
fileOut.close();
System.out.println("Serialized foo");
System.out.print("bar = ");
System.out.println(foo.getBar());
foo = null;
FileInputStream fileIn = new FileInputStream("./ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
foo = (Foo) in.readObject();
in.close();
fileIn.close();
System.out.println("Unserialized foo");
System.out.print("bar = ");
System.out.println(foo.getBar());
}
}
To compare that with PHP's behavior, I've written the following script:
---- demo.php ----
<?php
class Foo
{
protected $bar;
public function __construct() {
echo "Constructor of Foo called\n";
$this->bar = 0;
}
public function getBar() {
return $this->bar;
}
public function setBar($value) {
$this->bar = $value;
}
}
$foo = new Foo();
$foo->setBar(42);
file_put_contents('./ser', serialize($foo));
echo "Serialized foo\nbar = ", $foo->getBar(), "\n";
$foo = null;
$foo = unserialize(file_get_contents('./ser'));
echo "Unserialized foo\nbar = ", $foo->getBar(), "\n";
Running the java programm and the PHP script (PHP 5.4.19 cli) produces
the following output:
Constructor of Foo called
Serialized foo
bar = 42
Unserialized foo
bar = 42
Any conclusions are left to the reader.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185135 is a reply to message #185134] |
Fri, 28 February 2014 14:08 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/28/2014 8:52 AM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/27/2014 12:28 PM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> No matter how you look at it, PHP's implementation violates OO
>>>> >> principles and works differently than any other OO language.
>>>> >
>>>> > You have claimed that often enough, but yet you have not brought any
>>>> > proof.
>>>> >
>>>> > E.g. what happens in Java if an object that implements the
>>>> > java.io.Serializable interface is given as argument to
>>>> > java.io.OutputStream.writeObject()? Is the destructor called?
>>>> >
>>>>
>>>> Yes, it is.
>>>
>>> I strongly doubt that. On one hand this would mean you can't use the
>>> object as soon as it has been written to the stream, and on the other
>>> hand there are no *destructors* in Java (finalize() is similar to a
>>> destructor, but it is not guaranteed that it will be called).
>>> Furthermore it depends on the garbage collector, when an object will be
>>> *destroyed*.
>>>
>>>> But when the new object is created, a constructor is
>>>> called. You cannot unserialize an object without a constructor being
>>>> called first.
>>>
>>> I doubt that, too. After all, java.io.ObjectInputStream.readObject()
>>> returns an object, which of course has to be *created* -- but there's no
>>> need to call its *constructor*.
>>>
>>
>> No, because the constructor is called automatically.
>
> Wrong, see below.
>
>>> However, I believe our dissent mainly stems from different use of terms.
>>> I am accustomed to understand constructor/destructor as user defined
>>> functions (which can be defined for custom initialization/finalization
>>> tasks), while this may not be the common definition.
>>>
>>
>> They may be user defined, or they may be defined by the system (as in
>> the absence of a user-defined constructor).
>>
>>> When you're talking about OO principles wrt. to
>>> construction/destruction, you're most likely referring to RAII, which is
>>> not necessarily a general OO principle, and might not be possible to be
>>> cleanly implemented in garbage collected languages generally (consider
>>> cyclic references).
>>>
>>
>> No, I am not referring to RAII. I am referring to basic OO principles.
>>
>>> Anyway, I somewhat consider this discussion as harping on about
>>> principles, and I still don't see that PHP lacks the really important
>>> concepts regarding object (de)serialization and cloning.
>>>
>>
>> Just that it doesn't follow OO principles - which has caused me problems
>> in the past.
>
> To shorten further discussion I have installed the JDK 7u51, and written
> the following classes:
>
> ---- Foo.java ----
> public class Foo implements java.io.Serializable {
> protected int bar;
> public Foo() {
> System.out.println("Constructor of Foo called");
> bar = 0;
> }
> public int getBar() {
> return bar;
> }
> public void setBar(int value) {
> bar = value;
> }
> }
>
> ---- Demo.java ----
> import java.io.*;
>
> public class Demo {
> public static void main(String[] args)
> throws IOException, ClassNotFoundException {
> Foo foo = new Foo();
> foo.setBar(42);
> FileOutputStream fileOut = new FileOutputStream("./ser");
> ObjectOutputStream out = new ObjectOutputStream(fileOut);
> out.writeObject(foo);
> out.close();
> fileOut.close();
> System.out.println("Serialized foo");
> System.out.print("bar = ");
> System.out.println(foo.getBar());
> foo = null;
> FileInputStream fileIn = new FileInputStream("./ser");
> ObjectInputStream in = new ObjectInputStream(fileIn);
> foo = (Foo) in.readObject();
> in.close();
> fileIn.close();
> System.out.println("Unserialized foo");
> System.out.print("bar = ");
> System.out.println(foo.getBar());
> }
> }
>
> To compare that with PHP's behavior, I've written the following script:
>
> ---- demo.php ----
> <?php
>
> class Foo
> {
> protected $bar;
> public function __construct() {
> echo "Constructor of Foo called\n";
> $this->bar = 0;
> }
> public function getBar() {
> return $this->bar;
> }
> public function setBar($value) {
> $this->bar = $value;
> }
> }
>
> $foo = new Foo();
> $foo->setBar(42);
> file_put_contents('./ser', serialize($foo));
> echo "Serialized foo\nbar = ", $foo->getBar(), "\n";
> $foo = null;
> $foo = unserialize(file_get_contents('./ser'));
> echo "Unserialized foo\nbar = ", $foo->getBar(), "\n";
>
> Running the java programm and the PHP script (PHP 5.4.19 cli) produces
> the following output:
>
> Constructor of Foo called
> Serialized foo
> bar = 42
> Unserialized foo
> bar = 42
>
> Any conclusions are left to the reader.
>
Which shows just how little you understand programming.
In either case you have not created a new Foo object before serializing;
you have only serialized into an existing object. So obviously no
constructor is called.
Your stoopidity is amazing.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185136 is a reply to message #185135] |
Fri, 28 February 2014 15:52 |
Christoph Michael Bec
Messages: 207 Registered: June 2013
Karma: 0
|
Senior Member |
|
|
Jerry Stuckle wrote:
> On 2/28/2014 8:52 AM, Christoph Michael Becker wrote:
>> Jerry Stuckle wrote:
>>
>>> On 2/27/2014 12:28 PM, Christoph Michael Becker wrote:
>>>> Jerry Stuckle wrote:
>>>>
>>>> > On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>>>> >> Jerry Stuckle wrote:
>>>> >>
>>>> >>> No matter how you look at it, PHP's implementation violates OO
>>>> >>> principles and works differently than any other OO language.
>>>> >>
>>>> >> You have claimed that often enough, but yet you have not brought any
>>>> >> proof.
>>>> >>
>>>> >> E.g. what happens in Java if an object that implements the
>>>> >> java.io.Serializable interface is given as argument to
>>>> >> java.io.OutputStream.writeObject()? Is the destructor called?
>>>> >>
>>>> >
>>>> > Yes, it is.
>>>>
>>>> I strongly doubt that. On one hand this would mean you can't use the
>>>> object as soon as it has been written to the stream, and on the other
>>>> hand there are no *destructors* in Java (finalize() is similar to a
>>>> destructor, but it is not guaranteed that it will be called).
>>>> Furthermore it depends on the garbage collector, when an object will be
>>>> *destroyed*.
>>>>
>>>> > But when the new object is created, a constructor is
>>>> > called. You cannot unserialize an object without a constructor being
>>>> > called first.
>>>>
>>>> I doubt that, too. After all, java.io.ObjectInputStream.readObject()
>>>> returns an object, which of course has to be *created* -- but
>>>> there's no
>>>> need to call its *constructor*.
>>>>
>>>
>>> No, because the constructor is called automatically.
>>
>> Wrong, see below.
>>
>>>> However, I believe our dissent mainly stems from different use of
>>>> terms.
>>>> I am accustomed to understand constructor/destructor as user defined
>>>> functions (which can be defined for custom initialization/finalization
>>>> tasks), while this may not be the common definition.
>>>>
>>>
>>> They may be user defined, or they may be defined by the system (as in
>>> the absence of a user-defined constructor).
>>>
>>>> When you're talking about OO principles wrt. to
>>>> construction/destruction, you're most likely referring to RAII,
>>>> which is
>>>> not necessarily a general OO principle, and might not be possible to be
>>>> cleanly implemented in garbage collected languages generally (consider
>>>> cyclic references).
>>>>
>>>
>>> No, I am not referring to RAII. I am referring to basic OO principles.
>>>
>>>> Anyway, I somewhat consider this discussion as harping on about
>>>> principles, and I still don't see that PHP lacks the really important
>>>> concepts regarding object (de)serialization and cloning.
>>>>
>>>
>>> Just that it doesn't follow OO principles - which has caused me problems
>>> in the past.
>>
>> To shorten further discussion I have installed the JDK 7u51, and written
>> the following classes:
>>
>> ---- Foo.java ----
>> public class Foo implements java.io.Serializable {
>> protected int bar;
>> public Foo() {
>> System.out.println("Constructor of Foo called");
>> bar = 0;
>> }
>> public int getBar() {
>> return bar;
>> }
>> public void setBar(int value) {
>> bar = value;
>> }
>> }
>>
>> ---- Demo.java ----
>> import java.io.*;
>>
>> public class Demo {
>> public static void main(String[] args)
>> throws IOException, ClassNotFoundException {
>> Foo foo = new Foo();
>> foo.setBar(42);
>> FileOutputStream fileOut = new FileOutputStream("./ser");
>> ObjectOutputStream out = new ObjectOutputStream(fileOut);
>> out.writeObject(foo);
>> out.close();
>> fileOut.close();
>> System.out.println("Serialized foo");
>> System.out.print("bar = ");
>> System.out.println(foo.getBar());
>> foo = null;
>> FileInputStream fileIn = new FileInputStream("./ser");
>> ObjectInputStream in = new ObjectInputStream(fileIn);
>> foo = (Foo) in.readObject();
>> in.close();
>> fileIn.close();
>> System.out.println("Unserialized foo");
>> System.out.print("bar = ");
>> System.out.println(foo.getBar());
>> }
>> }
>>
>> To compare that with PHP's behavior, I've written the following script:
>>
>> ---- demo.php ----
>> <?php
>>
>> class Foo
>> {
>> protected $bar;
>> public function __construct() {
>> echo "Constructor of Foo called\n";
>> $this->bar = 0;
>> }
>> public function getBar() {
>> return $this->bar;
>> }
>> public function setBar($value) {
>> $this->bar = $value;
>> }
>> }
>>
>> $foo = new Foo();
>> $foo->setBar(42);
>> file_put_contents('./ser', serialize($foo));
>> echo "Serialized foo\nbar = ", $foo->getBar(), "\n";
>> $foo = null;
>> $foo = unserialize(file_get_contents('./ser'));
>> echo "Unserialized foo\nbar = ", $foo->getBar(), "\n";
>>
>> Running the java programm and the PHP script (PHP 5.4.19 cli) produces
>> the following output:
>>
>> Constructor of Foo called
>> Serialized foo
>> bar = 42
>> Unserialized foo
>> bar = 42
>>
>> Any conclusions are left to the reader.
>>
>
> Which shows just how little you understand programming.
>
> In either case you have not created a new Foo object before serializing;
> you have only serialized into an existing object. So obviously no
> constructor is called.
Of course, I have created a new Foo object before serializing in both
cases. You're probably talking about the unserializing code (please
look up the difference), but in this case your statement is wrong, as I
have assigned null to $foo (what would not have been necessary, though).
However, maybe you want
$foo = null;
replaced by
$foo = new Foo();
(resp. for the Java code). While the only benefit of this change would
be to keep the processor busy, it does no real harm (unless in a not
garbage collected environment, where it would create a memory leak).
So what do you think (or rather guess), the last line of the output
would be when changing the code repectively? Answer: bar = 42. That
proofs that the constructor is not called on the unserialized object.
Anyway, both programs behave equivalent, so Java also does not follow
basic OO principles wrt. to object (un)serialization, according to your
claim. However, you have stated it would, so obviously there's a
contradiction.
> Your stoopidity is amazing.
You may consider changing your attitude to not make a fool of you in the
public, again.
--
Christoph M. Becker
|
|
|
Re: Object constructors/destructors [message #185137 is a reply to message #185136] |
Fri, 28 February 2014 16:03 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 2/28/2014 10:52 AM, Christoph Michael Becker wrote:
> Jerry Stuckle wrote:
>
>> On 2/28/2014 8:52 AM, Christoph Michael Becker wrote:
>>> Jerry Stuckle wrote:
>>>
>>>> On 2/27/2014 12:28 PM, Christoph Michael Becker wrote:
>>>> > Jerry Stuckle wrote:
>>>> >
>>>> >> On 2/26/2014 5:39 PM, Christoph Michael Becker wrote:
>>>> >>> Jerry Stuckle wrote:
>>>> >>>
>>>> >>>> No matter how you look at it, PHP's implementation violates OO
>>>> >>>> principles and works differently than any other OO language.
>>>> >>>
>>>> >>> You have claimed that often enough, but yet you have not brought any
>>>> >>> proof.
>>>> >>>
>>>> >>> E.g. what happens in Java if an object that implements the
>>>> >>> java.io.Serializable interface is given as argument to
>>>> >>> java.io.OutputStream.writeObject()? Is the destructor called?
>>>> >>>
>>>> >>
>>>> >> Yes, it is.
>>>> >
>>>> > I strongly doubt that. On one hand this would mean you can't use the
>>>> > object as soon as it has been written to the stream, and on the other
>>>> > hand there are no *destructors* in Java (finalize() is similar to a
>>>> > destructor, but it is not guaranteed that it will be called).
>>>> > Furthermore it depends on the garbage collector, when an object will be
>>>> > *destroyed*.
>>>> >
>>>> >> But when the new object is created, a constructor is
>>>> >> called. You cannot unserialize an object without a constructor being
>>>> >> called first.
>>>> >
>>>> > I doubt that, too. After all, java.io.ObjectInputStream.readObject()
>>>> > returns an object, which of course has to be *created* -- but
>>>> > there's no
>>>> > need to call its *constructor*.
>>>> >
>>>>
>>>> No, because the constructor is called automatically.
>>>
>>> Wrong, see below.
>>>
>>>> > However, I believe our dissent mainly stems from different use of
>>>> > terms.
>>>> > I am accustomed to understand constructor/destructor as user defined
>>>> > functions (which can be defined for custom initialization/finalization
>>>> > tasks), while this may not be the common definition.
>>>> >
>>>>
>>>> They may be user defined, or they may be defined by the system (as in
>>>> the absence of a user-defined constructor).
>>>>
>>>> > When you're talking about OO principles wrt. to
>>>> > construction/destruction, you're most likely referring to RAII,
>>>> > which is
>>>> > not necessarily a general OO principle, and might not be possible to be
>>>> > cleanly implemented in garbage collected languages generally (consider
>>>> > cyclic references).
>>>> >
>>>>
>>>> No, I am not referring to RAII. I am referring to basic OO principles.
>>>>
>>>> > Anyway, I somewhat consider this discussion as harping on about
>>>> > principles, and I still don't see that PHP lacks the really important
>>>> > concepts regarding object (de)serialization and cloning.
>>>> >
>>>>
>>>> Just that it doesn't follow OO principles - which has caused me problems
>>>> in the past.
>>>
>>> To shorten further discussion I have installed the JDK 7u51, and written
>>> the following classes:
>>>
>>> ---- Foo.java ----
>>> public class Foo implements java.io.Serializable {
>>> protected int bar;
>>> public Foo() {
>>> System.out.println("Constructor of Foo called");
>>> bar = 0;
>>> }
>>> public int getBar() {
>>> return bar;
>>> }
>>> public void setBar(int value) {
>>> bar = value;
>>> }
>>> }
>>>
>>> ---- Demo.java ----
>>> import java.io.*;
>>>
>>> public class Demo {
>>> public static void main(String[] args)
>>> throws IOException, ClassNotFoundException {
>>> Foo foo = new Foo();
>>> foo.setBar(42);
>>> FileOutputStream fileOut = new FileOutputStream("./ser");
>>> ObjectOutputStream out = new ObjectOutputStream(fileOut);
>>> out.writeObject(foo);
>>> out.close();
>>> fileOut.close();
>>> System.out.println("Serialized foo");
>>> System.out.print("bar = ");
>>> System.out.println(foo.getBar());
>>> foo = null;
>>> FileInputStream fileIn = new FileInputStream("./ser");
>>> ObjectInputStream in = new ObjectInputStream(fileIn);
>>> foo = (Foo) in.readObject();
>>> in.close();
>>> fileIn.close();
>>> System.out.println("Unserialized foo");
>>> System.out.print("bar = ");
>>> System.out.println(foo.getBar());
>>> }
>>> }
>>>
>>> To compare that with PHP's behavior, I've written the following script:
>>>
>>> ---- demo.php ----
>>> <?php
>>>
>>> class Foo
>>> {
>>> protected $bar;
>>> public function __construct() {
>>> echo "Constructor of Foo called\n";
>>> $this->bar = 0;
>>> }
>>> public function getBar() {
>>> return $this->bar;
>>> }
>>> public function setBar($value) {
>>> $this->bar = $value;
>>> }
>>> }
>>>
>>> $foo = new Foo();
>>> $foo->setBar(42);
>>> file_put_contents('./ser', serialize($foo));
>>> echo "Serialized foo\nbar = ", $foo->getBar(), "\n";
>>> $foo = null;
>>> $foo = unserialize(file_get_contents('./ser'));
>>> echo "Unserialized foo\nbar = ", $foo->getBar(), "\n";
>>>
>>> Running the java programm and the PHP script (PHP 5.4.19 cli) produces
>>> the following output:
>>>
>>> Constructor of Foo called
>>> Serialized foo
>>> bar = 42
>>> Unserialized foo
>>> bar = 42
>>>
>>> Any conclusions are left to the reader.
>>>
>>
>> Which shows just how little you understand programming.
>>
>> In either case you have not created a new Foo object before serializing;
>> you have only serialized into an existing object. So obviously no
>> constructor is called.
>
> Of course, I have created a new Foo object before serializing in both
> cases. You're probably talking about the unserializing code (please
> look up the difference), but in this case your statement is wrong, as I
> have assigned null to $foo (what would not have been necessary, though).
>
> However, maybe you want
>
> $foo = null;
>
> replaced by
>
> $foo = new Foo();
>
> (resp. for the Java code). While the only benefit of this change would
> be to keep the processor busy, it does no real harm (unless in a not
> garbage collected environment, where it would create a memory leak).
>
> So what do you think (or rather guess), the last line of the output
> would be when changing the code repectively? Answer: bar = 42. That
> proofs that the constructor is not called on the unserialized object.
>
> Anyway, both programs behave equivalent, so Java also does not follow
> basic OO principles wrt. to object (un)serialization, according to your
> claim. However, you have stated it would, so obviously there's a
> contradiction.
>
>> Your stoopidity is amazing.
>
> You may consider changing your attitude to not make a fool of you in the
> public, again.
>
Yes, you continue to make a fool of yourself in public - as your last
statement shows. You have absolutely NO idea what you are talking
about, or how OO works.
I correspond off-list with some knowledgeable people who have followed
this conversation. They can't believe I even try to educate you. It's
like teaching a pig to sing.
And I'm through wasting my time. Your comments aren't even worth a
response (which is why I also refused to fall into your trap as to how I
define an "expression").
You don't discuss. You argue for the sake of argument.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185140 is a reply to message #185121] |
Sat, 01 March 2014 17:56 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 2/27/14, 8:25 AM, Jerry Stuckle wrote:
> On 2/26/2014 11:49 PM, Richard Damon wrote:
>> On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
>>> On 2/26/2014 7:50 AM, Richard Damon wrote:
>>>>
>>>> An the "name" of the Deserializing constructor in PHP is __wakeup().
>>>>
>>>> You also do NOT get two destructor calls on the same object, the
>>>> deserializing created a new object.
>>>>
>>>
>>> __wakeup() is not a constructor - and does not do the same thing.
>>>
>>
>> What makes it NOT a constructor? IT seems to be exactly the thing that
>> does what you say must be done to make the new object via
>> unserialization.
>>
>
> If you want to consider __wakeup() to be a constructor, then you must
> consider __sleep() to be a destructor. In that case, PHP is also wrong
> because if an object is serialized, it will call both __sleep() and the
> destructor. This would be two calls to destructors for the same object.
>
WHY does __sleep() need to be a destructor?
__sleep() is a function to control how an object is serialized, and the
object, as you seem to know, still exists, so no destructor should
happen at this point, in fact, if you look at it, __sleep() has not
expected to have any effect on the current object, its purpose is to
make sure that __wakeup() will get all the data it needs, and allow the
removal of data that it won't need.
|
|
|
Re: Operator precedence [message #185141 is a reply to message #185056] |
Sat, 01 March 2014 18:39 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 2/24/14, 11:59 PM, Jerry Stuckle wrote:
> On 2/24/2014 10:41 PM, Richard Damon wrote:
>> On 2/24/14, 7:00 AM, Jerry Stuckle wrote:
>>
>>> What language gives every possible way for you to screw up your
>>> programming?
>>>
>>> If you want to find out how some screwed-up code works in ANY language,
>>> you try it and find out.
>>>
>>
>> Herein lies the path to madness.
>>
>> Take the following C code
>>
>> #include <stdio.h>
>>
>> int main() {
>> int i = 4;
>> i = ++i + i++;
>> printf("%i\n", i);
>> return 0;
>> }
>>
>> Question, you want to find out what this is supposed to do. By your
>> statement, you run it on a system. The problem is that the answer you
>> get is only valid for THAT system, and possible for that EXACT piece of
>> code.
>>
>
> No, it shows how it works with THIS compiler. Not even this system - a
> different compiler may give different results. But then the same is
> true for ANY compiler.
>
> But then all I claimed was to try it and see how it works for THIS system.
>
> For instance, what is the output of:
>
> int main() {
> int i = 1;
> int j = i << 32;
> printf("%d\n", j);
> ?>
>
The C language spec makes this clear.
The result of 1 << 32 will be 4,294,967,206.
Now, if INT_MAX is defined to be a smaller value, then the program has
performed "undefined behavior", and the standard provides no constraints
on what happens after that point.
In common terms, if int is a type of at least 34 bits, (to include the
sign bit), this program has defined behavior, and the standard defines
its operation. if int is only a 33 bit type (or smaller), then the
compiler is not obligated to make this work. Practically, you are apt to
get either the result 0 or 1, (0 if the machine actually does the
shifting, 1 if the machine ignores extra shift count bits), but anything
is allowed.
>> The REAL answer is you compare the code to the formal specification of
>> the language, and you get the answer.
>>
>
> IF you have the formal specification available, and are able to
> understand it.
>
Not understanding the formal specification is a programmer issue. A
formal language CAN be used without access (or understanding) of the
formal specification through other documentation, and in fact, most
programmers can do a lot without needing to refer to the formal
specifications. The mere existence of them provides a "higher court" to
take issue that seem to come up, and figure out if the documentation or
the implementation has a problem when something doesn't seem right.
>> Too many people use your answer, and then complain because they get a
>> different answer on another machine, or in different circumstances, and
>> then complain that the compiler is "broken", when the real answer is
>> that THEIR program was the one that was broken.
>>
>> (For those not familiar with C, the answer in this case is that the
>> program has performed "undefined behavior" by modifying i twice without
>> a sequence point, and thus *ANY* resultant behavior is acceptable.
>>
>
> That is true - and you will not find your example in the ANSI C spec -
> which is why its output is not defined.
>
>> Here is a question, does PHP's documentation promise how the equivalent
>> PHP statement will execute?
>>
>> ...
>
> You tell me.
>
YOU made the claim that PHP is rigorously defined. Person making
assertion tends to have burden of proof. Lack of definition would be an
indication that it is NOT so rigorously defined.
>>
>>
>>>> The assignment operators in PHP have, in effect, different precedences
>>>> on the left and the right (a feature that some languages flaunt) but
>>>> that is not common and certainly not part of what I'd call basic
>>>> knowledge. The documentation gives one example of this peculiarity,
>>>> but
>>>> that does not clear the matter up conclusively. For example, in some
>>>> languages permit assignment to the result of a conditional expression,
>>>> but I think it's hard to tell from the documentation what these two do:
>>>>
>>>> $bool ? $a : $b = 42;
>>>> ($bool ? $a : $b) = 42;
>>>>
>>>
>>> Show me what language provides you with examples of every possible
>>> combination of operators and expressions.
>>
>> Read the C Grammer definition. It precisely describes how ANY expression
>> is to be parsed.
>>
>> It does give the compiler freedom to choose the order to execute the
>> parse tree, so things without inherent order have no promise of order,
>> but this is made explicit.
>>
>
> I have - many times while working on updating C courses. So much, in
> fact, that I completely wore out the ANSI spec I had (and which cost me
> a bunch of $$$).
>
> The spec specifies the order that operators are evaluated. It does NOT
> specify the order in which operands are evaluated. That is why your
> example has undefined results - the spec does not define what should
> happen.
>
Actually, the specification DOES say what happens, the program has
invoked undefined behavior, and any further actions are beyond the scope
of the standard. This IS a precise statement, it may not be real useful
to the programmer figure out predict what will happen, but it does
provide "rules of engagement" for writing programs. The programmer
promises to make sure the code doesn't invoke undefined behavior, and
the standard(s) will define what the program does.
>>
>>>
>>>> The operator precedence table suggests that both mean the same thing,
>>>> but they don't. I don't think the meaning of either is easily
>>>> determined from the documentation.
>>>>
>>>> <snip>
>>>>
>>>
>>> So you try it out, as you do in any language. But just because you can
>>> come up with some weird combination of operators which isn't listed in
>>> the doc does not mean the language is not rigorously defined.
>>> with
>>> But it does mean you are trolling.
>>>
>>
>> Rigorously defined would mean "precisely or exactly defined", which,
>> yes, does say that if you can come up with a "weird" combination, that
>> is not documented as to what is to happen, the definition is not
>> rigorous. A Formal definition, will be complete, as that is part of
>> being formal.
>>
>
> PHP is defined as rigorously as other languages. Just in a more
> reader-friendly way. (It took me a long time to figure out my way
> through the ANSI C spec - and even longer for SQL).
>
> But then since you seem to hate PHP so much, I suggest you just find
> another language more to your liking and stop wasting people's time in a
> PHP newsgroup. More trolls we don't need.
>
I don't hate PHP, in fact I find it a very useful language for many usages.
IF you want to claim that PHP is as rigorously defined as a language
like C, then perhaps your problem is you don't understand what rigorous
really means, and where it is useful in defining things.
PHP is NOT "rigorously" defined, its documentation is predominately
"natural language" based, not on formal grammar. This does have
advantages for the "common" programmer, making it easier to learn the
basics of the language, but does leave some minor details, which aren't
normally important poorly defined. Since PHP is predominately a "single
implementation language", it can get away with this.
One other effect of this is that in PHP, it is possible to file a
"documentation bug" for the documentation differing from how the
compiler operates. (this might result in a documentation change, or it
might be determined that it really is a program bug). With a formal
language, the only "bugs" that could be filed against the standard would
be a case where the documentation was in conflict with itself, otherwise
and discrepancy between the documentation and an implementation is, by
definition, a non-conformity in the implementation.
|
|
|
Re: Object constructors/destructors [message #185142 is a reply to message #185140] |
Sat, 01 March 2014 19:22 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 3/1/2014 12:56 PM, Richard Damon wrote:
> On 2/27/14, 8:25 AM, Jerry Stuckle wrote:
>> On 2/26/2014 11:49 PM, Richard Damon wrote:
>>> On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
>>>> On 2/26/2014 7:50 AM, Richard Damon wrote:
>>>> >
>>>> > An the "name" of the Deserializing constructor in PHP is __wakeup().
>>>> >
>>>> > You also do NOT get two destructor calls on the same object, the
>>>> > deserializing created a new object.
>>>> >
>>>>
>>>> __wakeup() is not a constructor - and does not do the same thing.
>>>>
>>>
>>> What makes it NOT a constructor? IT seems to be exactly the thing that
>>> does what you say must be done to make the new object via
>>> unserialization.
>>>
>>
>> If you want to consider __wakeup() to be a constructor, then you must
>> consider __sleep() to be a destructor. In that case, PHP is also wrong
>> because if an object is serialized, it will call both __sleep() and the
>> destructor. This would be two calls to destructors for the same object.
>>
>
> WHY does __sleep() need to be a destructor?
>
> __sleep() is a function to control how an object is serialized, and the
> object, as you seem to know, still exists, so no destructor should
> happen at this point, in fact, if you look at it, __sleep() has not
> expected to have any effect on the current object, its purpose is to
> make sure that __wakeup() will get all the data it needs, and allow the
> removal of data that it won't need.
>
If you are going to claim __wakeup() is a constructor, then you have to
agree that it's opposite (__sleep()) is a destructor. Otherwise you are
being inconsistent.
You can't just make up rules as you see fit!
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Operator precedence [message #185143 is a reply to message #185141] |
Sat, 01 March 2014 19:29 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 3/1/2014 1:39 PM, Richard Damon wrote:
> On 2/24/14, 11:59 PM, Jerry Stuckle wrote:
>> On 2/24/2014 10:41 PM, Richard Damon wrote:
>>> On 2/24/14, 7:00 AM, Jerry Stuckle wrote:
>>>
>>>> What language gives every possible way for you to screw up your
>>>> programming?
>>>>
>>>> If you want to find out how some screwed-up code works in ANY language,
>>>> you try it and find out.
>>>>
>>>
>>> Herein lies the path to madness.
>>>
>>> Take the following C code
>>>
>>> #include <stdio.h>
>>>
>>> int main() {
>>> int i = 4;
>>> i = ++i + i++;
>>> printf("%i\n", i);
>>> return 0;
>>> }
>>>
>>> Question, you want to find out what this is supposed to do. By your
>>> statement, you run it on a system. The problem is that the answer you
>>> get is only valid for THAT system, and possible for that EXACT piece of
>>> code.
>>>
>>
>> No, it shows how it works with THIS compiler. Not even this system - a
>> different compiler may give different results. But then the same is
>> true for ANY compiler.
>>
>> But then all I claimed was to try it and see how it works for THIS system.
>>
>> For instance, what is the output of:
>>
>> int main() {
>> int i = 1;
>> int j = i << 32;
>> printf("%d\n", j);
>> ?>
>>
>
> The C language spec makes this clear.
>
> The result of 1 << 32 will be 4,294,967,206.
> Now, if INT_MAX is defined to be a smaller value, then the program has
> performed "undefined behavior", and the standard provides no constraints
> on what happens after that point.
>
In my compiler, the output is 0. And it is ANSI compliant.
> In common terms, if int is a type of at least 34 bits, (to include the
> sign bit), this program has defined behavior, and the standard defines
> its operation. if int is only a 33 bit type (or smaller), then the
> compiler is not obligated to make this work. Practically, you are apt to
> get either the result 0 or 1, (0 if the machine actually does the
> shifting, 1 if the machine ignores extra shift count bits), but anything
> is allowed.
>
This has nothing to do with the subject - which is the size of an int.
>>> The REAL answer is you compare the code to the formal specification of
>>> the language, and you get the answer.
>>>
>>
>> IF you have the formal specification available, and are able to
>> understand it.
>>
>
> Not understanding the formal specification is a programmer issue. A
> formal language CAN be used without access (or understanding) of the
> formal specification through other documentation, and in fact, most
> programmers can do a lot without needing to refer to the formal
> specifications. The mere existence of them provides a "higher court" to
> take issue that seem to come up, and figure out if the documentation or
> the implementation has a problem when something doesn't seem right.
>
Yes, but when you're dealing with courseware, knowledge and
understanding of the specification is a very good idea.
>>> Too many people use your answer, and then complain because they get a
>>> different answer on another machine, or in different circumstances, and
>>> then complain that the compiler is "broken", when the real answer is
>>> that THEIR program was the one that was broken.
>>>
>>> (For those not familiar with C, the answer in this case is that the
>>> program has performed "undefined behavior" by modifying i twice without
>>> a sequence point, and thus *ANY* resultant behavior is acceptable.
>>>
>>
>> That is true - and you will not find your example in the ANSI C spec -
>> which is why its output is not defined.
>>
>
>
>>> Here is a question, does PHP's documentation promise how the equivalent
>>> PHP statement will execute?
>>>
>>> ...
>>
>> You tell me.
>>
>
> YOU made the claim that PHP is rigorously defined. Person making
> assertion tends to have burden of proof. Lack of definition would be an
> indication that it is NOT so rigorously defined.
>
YOU made the first assertion - that PHP is NOT rigorously defined. So,
according to your "rules", you have to prove it - which you have not.
>>>
>>>
>>>> > The assignment operators in PHP have, in effect, different precedences
>>>> > on the left and the right (a feature that some languages flaunt) but
>>>> > that is not common and certainly not part of what I'd call basic
>>>> > knowledge. The documentation gives one example of this peculiarity,
>>>> > but
>>>> > that does not clear the matter up conclusively. For example, in some
>>>> > languages permit assignment to the result of a conditional expression,
>>>> > but I think it's hard to tell from the documentation what these two do:
>>>> >
>>>> > $bool ? $a : $b = 42;
>>>> > ($bool ? $a : $b) = 42;
>>>> >
>>>>
>>>> Show me what language provides you with examples of every possible
>>>> combination of operators and expressions.
>>>
>>> Read the C Grammer definition. It precisely describes how ANY expression
>>> is to be parsed.
>>>
>>> It does give the compiler freedom to choose the order to execute the
>>> parse tree, so things without inherent order have no promise of order,
>>> but this is made explicit.
>>>
>>
>> I have - many times while working on updating C courses. So much, in
>> fact, that I completely wore out the ANSI spec I had (and which cost me
>> a bunch of $$$).
>>
>> The spec specifies the order that operators are evaluated. It does NOT
>> specify the order in which operands are evaluated. That is why your
>> example has undefined results - the spec does not define what should
>> happen.
>>
>
> Actually, the specification DOES say what happens, the program has
> invoked undefined behavior, and any further actions are beyond the scope
> of the standard. This IS a precise statement, it may not be real useful
> to the programmer figure out predict what will happen, but it does
> provide "rules of engagement" for writing programs. The programmer
> promises to make sure the code doesn't invoke undefined behavior, and
> the standard(s) will define what the program does.
>
Actually, no, the specification does not say specifically what happens
in a case such as j = i++ + ++i; That is why the operation is
"undefined" - because nothing in the spec defines what should happen.
>>>
>>>>
>>>> > The operator precedence table suggests that both mean the same thing,
>>>> > but they don't. I don't think the meaning of either is easily
>>>> > determined from the documentation.
>>>> >
>>>> > <snip>
>>>> >
>>>>
>>>> So you try it out, as you do in any language. But just because you can
>>>> come up with some weird combination of operators which isn't listed in
>>>> the doc does not mean the language is not rigorously defined.
>>>> with
>>>> But it does mean you are trolling.
>>>>
>>>
>>> Rigorously defined would mean "precisely or exactly defined", which,
>>> yes, does say that if you can come up with a "weird" combination, that
>>> is not documented as to what is to happen, the definition is not
>>> rigorous. A Formal definition, will be complete, as that is part of
>>> being formal.
>>>
>>
>> PHP is defined as rigorously as other languages. Just in a more
>> reader-friendly way. (It took me a long time to figure out my way
>> through the ANSI C spec - and even longer for SQL).
>>
>> But then since you seem to hate PHP so much, I suggest you just find
>> another language more to your liking and stop wasting people's time in a
>> PHP newsgroup. More trolls we don't need.
>>
>
> I don't hate PHP, in fact I find it a very useful language for many usages.
>
> IF you want to claim that PHP is as rigorously defined as a language
> like C, then perhaps your problem is you don't understand what rigorous
> really means, and where it is useful in defining things.
>
I understand exactly what rigorous means. But you obviously think it
means "in arcane and hard to understand language". It does not.
> PHP is NOT "rigorously" defined, its documentation is predominately
> "natural language" based, not on formal grammar. This does have
> advantages for the "common" programmer, making it easier to learn the
> basics of the language, but does leave some minor details, which aren't
> normally important poorly defined. Since PHP is predominately a "single
> implementation language", it can get away with this.
>
And how does the language used make it not "rigorously defined". Prove
your statement - according to your rules.
> One other effect of this is that in PHP, it is possible to file a
> "documentation bug" for the documentation differing from how the
> compiler operates. (this might result in a documentation change, or it
> might be determined that it really is a program bug). With a formal
> language, the only "bugs" that could be filed against the standard would
> be a case where the documentation was in conflict with itself, otherwise
> and discrepancy between the documentation and an implementation is, by
> definition, a non-conformity in the implementation.
>
It's also possible to file a "documentation bug" with ANSI
documentation, also. It's handled differently, but ANSI understands
that even its documentation can have errors.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|
Re: Object constructors/destructors [message #185147 is a reply to message #185142] |
Sun, 02 March 2014 19:28 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 3/1/14, 2:22 PM, Jerry Stuckle wrote:
> On 3/1/2014 12:56 PM, Richard Damon wrote:
>> On 2/27/14, 8:25 AM, Jerry Stuckle wrote:
>>> On 2/26/2014 11:49 PM, Richard Damon wrote:
>>>> On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
>>>> > On 2/26/2014 7:50 AM, Richard Damon wrote:
>>>> >>
>>>> >> An the "name" of the Deserializing constructor in PHP is __wakeup().
>>>> >>
>>>> >> You also do NOT get two destructor calls on the same object, the
>>>> >> deserializing created a new object.
>>>> >>
>>>> >
>>>> > __wakeup() is not a constructor - and does not do the same thing.
>>>> >
>>>>
>>>> What makes it NOT a constructor? IT seems to be exactly the thing that
>>>> does what you say must be done to make the new object via
>>>> unserialization.
>>>>
>>>
>>> If you want to consider __wakeup() to be a constructor, then you must
>>> consider __sleep() to be a destructor. In that case, PHP is also wrong
>>> because if an object is serialized, it will call both __sleep() and the
>>> destructor. This would be two calls to destructors for the same object.
>>>
>>
>> WHY does __sleep() need to be a destructor?
>>
>> __sleep() is a function to control how an object is serialized, and the
>> object, as you seem to know, still exists, so no destructor should
>> happen at this point, in fact, if you look at it, __sleep() has not
>> expected to have any effect on the current object, its purpose is to
>> make sure that __wakeup() will get all the data it needs, and allow the
>> removal of data that it won't need.
>>
>
> If you are going to claim __wakeup() is a constructor, then you have to
> agree that it's opposite (__sleep()) is a destructor. Otherwise you are
> being inconsistent.
>
> You can't just make up rules as you see fit!
>
Then why are you claiming that something that isn't a desturctor must be
one.
Serialization, creates an external representation for an object, that is
what __sleep() is part of. This does NOT inherently involve the
destruction of the object (at least at that point).
Deserialization, on the other hand, creates an object from an external
representation. so it will involve the construction of a new object (you
can do "in-place" deserialization in some languages, where you first
create a dummy object, and then fill it in with the external data, but
this is normally a clumsy way to define it).
Note that the object oriented paradigm does have asymmetry in it. A
given type will tend to have multiple constructors, for the different
ways that an object might come into existence. There is usually only one
destructor. In PHP, one of these constructors is called __construct()
which is the general purpose constructor. (unlike in other statically
type languages, we can only define one of these). PHP also lets us
define a piece of the deserialing constructor with __wakeup() (PHP does
some of the heavy lifting here in parsing the serialized data and
setting up the object, __wakeup() is just required to do any final
needed operations after the values have been set.)
|
|
|
Re: Operator precedence [message #185148 is a reply to message #185143] |
Sun, 02 March 2014 20:22 |
Richard Damon
Messages: 58 Registered: August 2011
Karma: 0
|
Member |
|
|
On 3/1/14, 2:29 PM, Jerry Stuckle wrote:
> On 3/1/2014 1:39 PM, Richard Damon wrote:
>> On 2/24/14, 11:59 PM, Jerry Stuckle wrote:
>>>
>>> For instance, what is the output of:
>>>
>>> int main() {
>>> int i = 1;
>>> int j = i << 32;
>>> printf("%d\n", j);
>>> ?>
>>>
>>
>> The C language spec makes this clear.
>>
>> The result of 1 << 32 will be 4,294,967,206.
>> Now, if INT_MAX is defined to be a smaller value, then the program has
>> performed "undefined behavior", and the standard provides no constraints
>> on what happens after that point.
>>
>
> In my compiler, the output is 0. And it is ANSI compliant.
Which says that INT_MAX must be less than 4,294,967,206 and thus the
program has invoked undefined behavior so ANY output (including no
output) is compliant. This is clearly specified in the standard.
<snip>
>> YOU made the claim that PHP is rigorously defined. Person making
>> assertion tends to have burden of proof. Lack of definition would be an
>> indication that it is NOT so rigorously defined.
>>
>
> YOU made the first assertion - that PHP is NOT rigorously defined. So,
> according to your "rules", you have to prove it - which you have not.
>
This is easy.
Rigorous: severely exact or accurate; precise.
Thus to be rigorously defined, a language needs a severely exact or
accurate description of what the language is and what results of every
valid program will be.
For computer languages, this is traditionally done with formal
specifications and grammars. PHP does NOT provide us with one. (It is
hard to prove the non-existence of something, but a determined search of
the site does not reveal one, of course, it would be easy to disprove
this statement by pointing it the location of it).
I will agree that a formal grammar isn't absolutely required for a
rigorous definition, if enough care was taken to FULLY describe every
condition in a less formal manner. This clearly has not happened, as the
statement that caused all this discussion is not CLEARLY spelled out in
the documentation.
Namely, why does the statement
!$a && $a = 42;
bind the $a variable to the = operator even though the && operator has a
higher precedence?
Again, proof of absence is impossible, but a search of the documentation
does not find anything that defines this, further evidenced by that fact
that NO ONE in this thread has offered a statement from the
documentation that clearly indicates that this is how it must work.
THUS, it is proved, PHP is not rigorously defined.
<snip>
>> Actually, the specification DOES say what happens, the program has
>> invoked undefined behavior, and any further actions are beyond the scope
>> of the standard. This IS a precise statement, it may not be real useful
>> to the programmer figure out predict what will happen, but it does
>> provide "rules of engagement" for writing programs. The programmer
>> promises to make sure the code doesn't invoke undefined behavior, and
>> the standard(s) will define what the program does.
>>
>
> Actually, no, the specification does not say specifically what happens
> in a case such as j = i++ + ++i; That is why the operation is
> "undefined" - because nothing in the spec defines what should happen.
>
This is a non-sense statement. The C standard specifically defines the
results, using a specifically defined term, "undefined behavior".
Standards define a form of contract, that if the programmer follows a
few basic requirements, the standard will define what are the expected
results of the program. In C, one of those requirements is that the
program will not generate "undefined behavior". In essence, once a
program performs undefined behavior, the standard washes it hands of
what will result.
<snip>
>>
>> IF you want to claim that PHP is as rigorously defined as a language
>> like C, then perhaps your problem is you don't understand what rigorous
>> really means, and where it is useful in defining things.
>>
>
> I understand exactly what rigorous means. But you obviously think it
> means "in arcane and hard to understand language". It does not.
>
Rigor requires precision, something MUCH harder to do in conversational
language than in something more "precise". Formal grammars tend to be
much easier to be precise, and to verify that you have been complete.
>> PHP is NOT "rigorously" defined, its documentation is predominately
>> "natural language" based, not on formal grammar. This does have
>> advantages for the "common" programmer, making it easier to learn the
>> basics of the language, but does leave some minor details, which aren't
>> normally important poorly defined. Since PHP is predominately a "single
>> implementation language", it can get away with this.
>>
>
> And how does the language used make it not "rigorously defined". Prove
> your statement - according to your rules.
>
See above.
>> One other effect of this is that in PHP, it is possible to file a
>> "documentation bug" for the documentation differing from how the
>> compiler operates. (this might result in a documentation change, or it
>> might be determined that it really is a program bug). With a formal
>> language, the only "bugs" that could be filed against the standard would
>> be a case where the documentation was in conflict with itself, otherwise
>> and discrepancy between the documentation and an implementation is, by
>> definition, a non-conformity in the implementation.
>>
>
> It's also possible to file a "documentation bug" with ANSI
> documentation, also. It's handled differently, but ANSI understands
> that even its documentation can have errors.
>
As I said, a defect report can be filed for cases where the standard is
in conflict with itself or is unclear or ambiguous. These are errors in
the standard.
A defect report can NOT be filed because the standard says something is
to be done different than it is, or is wanted to be. These are NOT
"Defects" in the standard. A difference in behavior between an
implementation and what the standard requires is ALWAYS a non-conformity
of the implementation, and not an "error" in the standard (assuming it
isn't something in the standard being contradictory, etc).
|
|
|
Re: Object constructors/destructors [message #185149 is a reply to message #185147] |
Sun, 02 March 2014 20:42 |
Jerry Stuckle
Messages: 2598 Registered: September 2010
Karma: 0
|
Senior Member |
|
|
On 3/2/2014 2:28 PM, Richard Damon wrote:
> On 3/1/14, 2:22 PM, Jerry Stuckle wrote:
>> On 3/1/2014 12:56 PM, Richard Damon wrote:
>>> On 2/27/14, 8:25 AM, Jerry Stuckle wrote:
>>>> On 2/26/2014 11:49 PM, Richard Damon wrote:
>>>> > On 2/26/14, 8:44 AM, Jerry Stuckle wrote:
>>>> >> On 2/26/2014 7:50 AM, Richard Damon wrote:
>>>> >>>
>>>> >>> An the "name" of the Deserializing constructor in PHP is __wakeup().
>>>> >>>
>>>> >>> You also do NOT get two destructor calls on the same object, the
>>>> >>> deserializing created a new object.
>>>> >>>
>>>> >>
>>>> >> __wakeup() is not a constructor - and does not do the same thing.
>>>> >>
>>>> >
>>>> > What makes it NOT a constructor? IT seems to be exactly the thing that
>>>> > does what you say must be done to make the new object via
>>>> > unserialization.
>>>> >
>>>>
>>>> If you want to consider __wakeup() to be a constructor, then you must
>>>> consider __sleep() to be a destructor. In that case, PHP is also wrong
>>>> because if an object is serialized, it will call both __sleep() and the
>>>> destructor. This would be two calls to destructors for the same object.
>>>>
>>>
>>> WHY does __sleep() need to be a destructor?
>>>
>>> __sleep() is a function to control how an object is serialized, and the
>>> object, as you seem to know, still exists, so no destructor should
>>> happen at this point, in fact, if you look at it, __sleep() has not
>>> expected to have any effect on the current object, its purpose is to
>>> make sure that __wakeup() will get all the data it needs, and allow the
>>> removal of data that it won't need.
>>>
>>
>> If you are going to claim __wakeup() is a constructor, then you have to
>> agree that it's opposite (__sleep()) is a destructor. Otherwise you are
>> being inconsistent.
>>
>> You can't just make up rules as you see fit!
>>
>
> Then why are you claiming that something that isn't a desturctor must be
> one.
>
I'm not - you're the one claiming __wakeup() is a constructor, but it's
opposite, __sleep() is not a destructor.
> Serialization, creates an external representation for an object, that is
> what __sleep() is part of. This does NOT inherently involve the
> destruction of the object (at least at that point).
>
Then __wakeup() does NOT inherently involve creation of an object.
> Deserialization, on the other hand, creates an object from an external
> representation. so it will involve the construction of a new object (you
> can do "in-place" deserialization in some languages, where you first
> create a dummy object, and then fill it in with the external data, but
> this is normally a clumsy way to define it).
>
Not in other languages. It builds from an already existing object where
the constructor has been called.
> Note that the object oriented paradigm does have asymmetry in it. A
> given type will tend to have multiple constructors, for the different
> ways that an object might come into existence. There is usually only one
> destructor. In PHP, one of these constructors is called __construct()
> which is the general purpose constructor. (unlike in other statically
> type languages, we can only define one of these). PHP also lets us
> define a piece of the deserialing constructor with __wakeup() (PHP does
> some of the heavy lifting here in parsing the serialized data and
> setting up the object, __wakeup() is just required to do any final
> needed operations after the values have been set.)
>
Constructors are constructors, and the destructor is a destructor. No
asymmetry there. Except in PHP.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex(at)attglobal(dot)net
==================
|
|
|