On Thu, Dec 29, 2016 at 7:16 AM, Rasmus Schultz <[email protected]> wrote:
> Reading through those comments, I am if anything now more baffled.
>
> Looking at an implementation of attach() such as zend-diactoros, the
> implementation of attach() is precisely identical to that of __construct() -
> it effectively permits you to replace the entire object with a different
> object, e.g. provides a kind of mutability that enables you to replace the
> entire object.
>
> As far as I can figure, the only thing you can hope to accomplish with that,
> is side-effects - a degree of side-effects not even possible with native
> streams.
>
> And we wanted to avoid side-effects, right? That's why the rest of the model
> is immutable.
>
> Can you point me to a real-world example of attach() and detach() in use?

attach() exists in zend-diactoros because the library was developed in
tandem with PSR-7 development. Unfortunately, the method was never
removed. I plan to do so in the next major revision, and will be
marking it as deprecated in an upcoming minor release. Please ignore
the method when considering PSR-7; we omitted it from the spec for a
number of reasons.

First, as you note, it goes against the design of the rest of the
specification, which strives for immutability. Second, replacing the
underlying resource is something that is untenable: not all stream
implementations will be backed with the same type of resource, making
implementation essentially impossible. As an example, while the target
implementation is a PHP stream resource, we have also allowed for
callback, generator, and iterator-backed stream. What happens if you
provide one of these to an implementation that only supports PHP
streams? or a PHP stream to an implementation that expects a callback?

As such, we removed attach() from the spec. As I've also noted, I
neglected to remove it from Diactoros when that change happened. It's
not part of the spec; as a PSR-7 consumer, it's something you can
safely ignore.

The reason for having detach() was to allow access to the underlying
resource in order to perform operations not supported by the
interface. As an example, if you want to use stream_copy_to_stream()
to copy the stream to PHP's php://output stream more performantly, or
to copy an incoming stream to an HTTP client request stream, you would
need access to the underlying resource. Similarly, if you wanted to
use iterator_to_array() to cast an iterator- or generator-backed
stream to an array, you could pull the underlying resource. detach()
is _destructive_, however, because any such manipulations could
themselves alter the behavior of the underlying resource associated
with the StreamInterface. As an example, a read-only stream, when
read, would leave the StreamInterface implementation in unusable
state.

Hopefully the above helps clarify the purpose of detach(), and why
attach() was removed from the specification.

>
>
> On Thursday, December 29, 2016 at 1:48:42 PM UTC+1, Stefano Torresi wrote:
>>
>> Hey Rasmus,
>>
>> The detach() method was introduced to allow a fine grained control over
>> the underlying resource of the Stream object, and it provides a standardized
>> way to do that.
>> You can find more insights in the original discussion here:
>> https://groups.google.com/d/msg/php-fig/CTPRa2XP8po/kYZnFxl4JjMJ
>>
>> Admittedly, the metadoc is a bit lacking in this regard.
>>
>> I think we could amend it with a clarifying errata, couldn't we?
>>
>> Il giorno gio 29 dic 2016 alle ore 13:25 Rasmus Schultz
>> <[email protected]> ha scritto:
>>>
>>> The detach() method of StreamInterface in PSR-7 isn't mentioned anywhere
>>> in the documentation or meta.
>>>
>>> The only documentation for it, is the inline documentation, which doesn't
>>> explain what it's for:
>>>
>>> > Separates any underlying resources from the stream.
>>>
>>> So basically, this sets the internal resource handle (an implementation
>>> detail!) to null, right?
>>>
>>> > After the stream has been detached, the stream is in an unusable state.
>>>
>>> So if I want my stream object in an invalid, unusable state, this is the
>>> method to call.
>>>
>>> Huh?
>>>
>>> When would I want that?
>>>
>>> Since streams are (primarily) intended as wrappers around PHP
>>> stream-resource handles, I would have expected that the way to "detach" a
>>> StreamInterface instance from the native stream-resource handle, is to
>>> destroy the object - since a StreamInterface-wrapper around a PHP
>>> stream-resource handle really represents only one thing: the
>>> resource-handle.
>>>
>>> When would "detaching" and leaving the object in an invalid state make
>>> more sense than simply destroying the object, and thereby the reference to
>>> the stream-resource handle?
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "PHP Framework Interoperability Group" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [email protected].
>>> To post to this group, send email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/php-fig/99fd9037-331d-4645-ad0f-c911ae370356%40googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/php-fig/08a6b4ab-fcec-4ccc-8b0f-351cdf3612cd%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.



-- 
Matthew Weier O'Phinney
[email protected]
https://mwop.net/

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/CAJp_myU8HNs8y4YbgOt%3DAUHH47tCbewsfZmQn%2BnR0kO62W7hcQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to