I didn't mention the word internal, nor did I imply it; with
documentation stating that it would be used, it is clearly *not*
internal.

If you look at the code in question, you can see a probable reason why
a Lener interface is not used; for each of the blessed types, a
concrete copy of the pointed-to-value is made to allow GetBody to
return it. This cannot be done with an interface value without the use
of reflect.

Please show me a Len method in the standard library that does not
return the number of available-to-access elements in a collection.


On Thu, 2019-02-07 at 13:27 -0600, robert engels wrote:
> I am not following. You stated that the usage of Len was internal and
> a type switch on known concrete types, so how is related to how the
> OP was attempting to have things work?
> 
> There is no “generally accepted use of Len()”, otherwise it would not
> need to perform a type switch on known concrete types - it would cast
> to an interface declaring Len(), and use the interface, and then it
> would work with any type.
> 
> > 
> > On Feb 7, 2019, at 1:07 PM, Dan Kortschak <d...@kortschak.io> wrote:
> > 
> > Yeah, I'm not agreeing with you.
> > 
> > On Thu, 2019-02-07 at 07:07 -0600, Robert Engels wrote:
> > > 
> > > You are agreeing with me. A type switch on concrete types (that
> > > you
> > > control) is far different than using an available Len() method
> > > and
> > > assuming the same semantics. 
> > > 
> > > > 
> > > > 
> > > > On Feb 7, 2019, at 1:05 AM, Dan Kortschak <d...@kortschak.io>
> > > > wrote:
> > > > 
> > > > Addressing the first sentence, it was a direct answer to a
> > > > comment
> > > > you
> > > > made:
> > > > 
> > > > > 
> > > > > 
> > > > > But is it really? If you read the description for Len() on
> > > > > bytes.Buffer it is the length of unread portion. But that
> > > > > doesn’t
> > > > > mean the buffer isn’t just a portion of the entire body - it
> > > > > can
> > > > > be a
> > > > > chunk which is continually reloaded.
> > > > As far as the claim that there is a need to have a Len method
> > > > in
> > > > io.Reader, have a look at the code in question. It type asserts
> > > > on
> > > > three concrete types that are known to the function, all three
> > > > have
> > > > a
> > > > Len method and this is used to obtain the known length. All
> > > > other
> > > > io.Readers are considered to have an unknown length.
> > > > 
> > > > Whether it's wrong to use Len depends on whether there is a
> > > > generally
> > > > accepted and consistent set of semantics to Len() int. There
> > > > is.
> > > > This
> > > > is strengthened if the use of an existing Len method is noted
> > > > in
> > > > the
> > > > docs.
> > > > 
> > > > > 
> > > > > 
> > > > > On Wed, 2019-02-06 at 15:50 -0600, robert engels wrote:
> > > > > I am not sure what that has to do with the discussion. My
> > > > > point
> > > > > was
> > > > > that for it to be applicable here, it needs to be defined as
> > > > > part
> > > > > of
> > > > > io.Reader, since that is what Body is declared as. It is not,
> > > > > so
> > > > > using in the manner outlined is not correct IMO.
> > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > On Feb 6, 2019, at 3:37 PM, Dan Kortschak <d...@kortschak.io
> > > > > > >
> > > > > > wrote:
> > > > > > 
> > > > > > The generalised semantics of Len are that it returns the
> > > > > > number
> > > > > > of
> > > > > > available elements in the collection, being a cognate of
> > > > > > the
> > > > > > len
> > > > > > built-
> > > > > > in. This means that as you consume elements from a buffer,
> > > > > > the
> > > > > > Len
> > > > > > value reduces. This is directly equivalent to
> > > > > > 
> > > > > > for len(buf) != 0 {
> > > > > >    println(buf[0])
> > > > > >    buf = buf[1:]
> > > > > > }
> > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > On Wed, 2019-02-06 at 08:56 -0600, Robert Engels wrote:
> > > > > > > 
> > > > > > > But is it really? If you read the description for Len()
> > > > > > > on
> > > > > > > bytes.Buffer it is the length of unread portion. But that
> > > > > > > doesn’t
> > > > > > > mean the buffer isn’t just a portion of the entire body -
> > > > > > > it
> > > > > > > can
> > > > > > > be a
> > > > > > > chunk which is continually reloaded. 
> > > > > > > 
> > > > > > > This is the danger in using private APIs publically based
> > > > > > > upon
> > > > > > > the
> > > > > > > existence of a method - it leads to very brittle code -
> > > > > > > and
> > > > > > > there
> > > > > > > are
> > > > > > > almost certainly better ways to design it to avoid these
> > > > > > > issues.
> > > > > > > If
> > > > > > > the core api is not expressive enough then it will be
> > > > > > > more
> > > > > > > difficult. 
> > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > On Feb 6, 2019, at 8:30 AM, Burak Serdar <bserdar@ieee.
> > > > > > > > org>
> > > > > > > > wrote:
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > On Wed, Feb 6, 2019 at 5:15 AM Robert Engels <rengels
> > > > > > > > > @ix.
> > > > > > > > > netc
> > > > > > > > > om.c
> > > > > > > > > om> wrote:
> > > > > > > > > 
> > > > > > > > > I see now, but if that can be the case, shouldn’t the
> > > > > > > > > Body be
> > > > > > > > > documented that the Reader may be a ReaderWithLen,
> > > > > > > > > and
> > > > > > > > > the
> > > > > > > > > consumer is free to type check/cast? If not, you are
> > > > > > > > > using
> > > > > > > > > internal details that you should not be.
> > > > > > > > Yes, the documentation should say if the reader has a
> > > > > > > > Len()
> > > > > > > > method
> > > > > > > > it
> > > > > > > > would be used to set the ContentLength. Len is no
> > > > > > > > longer an
> > > > > > > > internal
> > > > > > > > detail then.
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > This is a problem with Go in general. Because the
> > > > > > > > > returned
> > > > > > > > > object
> > > > > > > > > “implements” some interface because it happens to
> > > > > > > > > have
> > > > > > > > > the
> > > > > > > > > required method, doesn’t mean it was designed to be
> > > > > > > > > used
> > > > > > > > > that
> > > > > > > > > way, or that it has the required semantics - unless
> > > > > > > > > documented to
> > > > > > > > > have them.
> > > > > > > > I agree with you there. Len() is straight forward, but
> > > > > > > > in
> > > > > > > > general
> > > > > > > > just
> > > > > > > > because a function is named something doesn't mean
> > > > > > > > it'll do
> > > > > > > > the
> > > > > > > > same
> > > > > > > > thing for all implementations. On the other end of the
> > > > > > > > spectrum
> > > > > > > > is
> > > > > > > > Java-like interfaces where you want explicit
> > > > > > > > inheritance of
> > > > > > > > a
> > > > > > > > specific
> > > > > > > > interface. I don't know if there's anything in between,
> > > > > > > > but
> > > > > > > > I
> > > > > > > > like
> > > > > > > > Go's approach much better.
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > On Feb 6, 2019, at 2:22 AM, Matteo Biagetti
> > > > > > > > > <matteo.biagetti@
> > > > > > > > > gmai
> > > > > > > > > l.com> wrote:
> > > > > > > > > 
> > > > > > > > > Make sense, thanks for explanation
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > Il giorno mercoledì 6 febbraio 2019 07:28:54 UTC+1,
> > > > > > > > > Burak
> > > > > > > > > Serdar
> > > > > > > > > ha scritto:
> > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > On Tue, Feb 5, 2019 at 8:13 PM robert engels <ren..
> > > > > > > > > > .@ix
> > > > > > > > > > .net
> > > > > > > > > > com.
> > > > > > > > > > com> wrote:
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > That’s what I was trying to point out. Your
> > > > > > > > > > > design is
> > > > > > > > > > > not
> > > > > > > > > > > correct. The Body is a Reader, not a Buffer - the
> > > > > > > > > > > length
> > > > > > > > > > > of
> > > > > > > > > > > the request/body may be indeterminate - that is,
> > > > > > > > > > > a
> > > > > > > > > > > stream.
> > > > > > > > > > > Attempting to get the length of an underlying
> > > > > > > > > > > buffer
> > > > > > > > > > > is
> > > > > > > > > > > not
> > > > > > > > > > > only probably not possible, but not correct in
> > > > > > > > > > > many
> > > > > > > > > > > situations.
> > > > > > > > > > The length of the body *may* be indeterminate, and
> > > > > > > > > > if
> > > > > > > > > > that's
> > > > > > > > > > the case,
> > > > > > > > > > the underlying Reader will not have a Len method.
> > > > > > > > > > The
> > > > > > > > > > design is
> > > > > > > > > > to
> > > > > > > > > > handle the case where the underlying Reader is a
> > > > > > > > > > Buffer
> > > > > > > > > > with a
> > > > > > > > > > Len
> > > > > > > > > > method. If the Reader has Len, then the NopCloser
> > > > > > > > > > derived
> > > > > > > > > > from
> > > > > > > > > > that
> > > > > > > > > > will also have a Len, and NewRequest can set the
> > > > > > > > > > content
> > > > > > > > > > length. If
> > > > > > > > > > the Reader does not have Len, then the content
> > > > > > > > > > length
> > > > > > > > > > is
> > > > > > > > > > unknown.
> > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > There is a reason the Body is a ReaderCloser and
> > > > > > > > > > > not
> > > > > > > > > > > a
> > > > > > > > > > > buffer. It is part of the http specification.
> > > > > > > > > > > 
> > > > > > > > > > > On Feb 5, 2019, at 9:00 PM, Burak Serdar <bse...@
> > > > > > > > > > > ieee
> > > > > > > > > > > .org
> > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > wrote:
> > > > > > > > > > > 
> > > > > > > > > > > On Tue, Feb 5, 2019 at 7:00 PM Robert Engels
> > > > > > > > > > > <ren...@
> > > > > > > > > > > ix.n
> > > > > > > > > > > etco
> > > > > > > > > > > m.com> wrote:
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > Shouldn’t you just be taking the content length
> > > > > > > > > > > from
> > > > > > > > > > > the
> > > > > > > > > > > header if forwarding the same body. There is no
> > > > > > > > > > > need
> > > > > > > > > > > for
> > > > > > > > > > > the
> > > > > > > > > > > length of the body.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > True. What I was suggesting is a fix for the
> > > > > > > > > > > general
> > > > > > > > > > > case.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > On Feb 5, 2019, at 6:53 PM, Burak Serdar <bse...@
> > > > > > > > > > > ieee
> > > > > > > > > > > .org
> > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > wrote:
> > > > > > > > > > > 
> > > > > > > > > > > On Tue, Feb 5, 2019 at 5:18 PM Dan Kortschak <d..
> > > > > > > > > > > .@ko
> > > > > > > > > > > rtsc
> > > > > > > > > > > hak.
> > > > > > > > > > > io> wrote:
> > > > > > > > > > > 
> > > > > > > > > > > Personally, I think this is a bug in the
> > > > > > > > > > > behaviour of
> > > > > > > > > > > NewRequest. See h
> > > > > > > > > > > ttps://github.com/golang/go/issues/18117 for some
> > > > > > > > > > > additional
> > > > > > > > > > > context.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > Agreed. One solution could be to have:
> > > > > > > > > > > 
> > > > > > > > > > > type HasLen interface {
> > > > > > > > > > > int Len()
> > > > > > > > > > > }
> > > > > > > > > > > 
> > > > > > > > > > > Then have NopCloser return a nopCloser with len
> > > > > > > > > > > if
> > > > > > > > > > > the
> > > > > > > > > > > underlying
> > > > > > > > > > > implementation has len, with the obvious changes
> > > > > > > > > > > to
> > > > > > > > > > > NewRequest.Ugly,
> > > > > > > > > > > but can be done without API changes.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > On Tue, 2019-02-05 at 05:18 -0800, matteo....@gma
> > > > > > > > > > > il.c
> > > > > > > > > > > om
> > > > > > > > > > > wrote:
> > > > > > > > > > > I've the following situation:
> > > > > > > > > > > I proxy a request to another server and when I
> > > > > > > > > > > made a
> > > > > > > > > > > POST
> > > > > > > > > > > and create
> > > > > > > > > > > a new
> > > > > > > > > > > request, the contentLength is zero:
> > > > > > > > > > > 
> > > > > > > > > > >      req2, _ := http.NewRequest(req.Method,
> > > > > > > > > > > newApiUrl
> > > > > > > > > > > ,
> > > > > > > > > > > req.Body)
> > > > > > > > > > >      fmt.Println("New request from body:",
> > > > > > > > > > > req2.ContentLength) //
> > > > > > > > > > > print 0
> > > > > > > > > > > 
> > > > > > > > > > > Checking in the source code of the NewRequest
> > > > > > > > > > > func
> > > > > > > > > > > Body
> > > > > > > > > > > don't
> > > > > > > > > > > respect
> > > > > > > > > > > some
> > > > > > > > > > > interface and populate the ContentLength field.
> > > > > > > > > > > 
> > > > > > > > > > > Could be a bug? Which could be a valid approach
> > > > > > > > > > > in
> > > > > > > > > > > order
> > > > > > > > > > > to
> > > > > > > > > > > create a
> > > > > > > > > > > new
> > > > > > > > > > > request from an existing one and correct set the
> > > > > > > > > > > Body
> > > > > > > > > > > length?
> > > > > > > > > > > 
> > > > > > > > > > > A working example here:
> > > > > > > > > > > 
> > > > > > > > > > > https://play.golang.org/p/SvCDLj0NrXb
> > > > > > > > > > > 
> > > > > > > > > > > Thanks!
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > --
> > > > > > > > > > > You received this message because you are
> > > > > > > > > > > subscribed
> > > > > > > > > > > to
> > > > > > > > > > > the
> > > > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > > > emails
> > > > > > > > > > > from
> > > > > > > > > > > it, send an email to golang-nuts...@googlegroups.
> > > > > > > > > > > com.
> > > > > > > > > > > For more options, visit https://groups.google.com
> > > > > > > > > > > /d/o
> > > > > > > > > > > ptou
> > > > > > > > > > > t.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > --
> > > > > > > > > > > You received this message because you are
> > > > > > > > > > > subscribed
> > > > > > > > > > > to
> > > > > > > > > > > the
> > > > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > > > emails
> > > > > > > > > > > from
> > > > > > > > > > > it, send an email to golang-nuts...@googlegroups.
> > > > > > > > > > > com.
> > > > > > > > > > > For more options, visit https://groups.google.com
> > > > > > > > > > > /d/o
> > > > > > > > > > > ptou
> > > > > > > > > > > t.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > --
> > > > > > > > > > > You received this message because you are
> > > > > > > > > > > subscribed
> > > > > > > > > > > to
> > > > > > > > > > > the
> > > > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > > > emails
> > > > > > > > > > > from
> > > > > > > > > > > it, send an email to golang-nuts...@googlegroups.
> > > > > > > > > > > com.
> > > > > > > > > > > For more options, visit https://groups.google.com
> > > > > > > > > > > /d/o
> > > > > > > > > > > ptou
> > > > > > > > > > > t.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > --
> > > > > > > > > > > You received this message because you are
> > > > > > > > > > > subscribed
> > > > > > > > > > > to
> > > > > > > > > > > the
> > > > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > > > emails
> > > > > > > > > > > from
> > > > > > > > > > > it, send an email to golang-nuts...@googlegroups.
> > > > > > > > > > > com.
> > > > > > > > > > > For more options, visit https://groups.google.com
> > > > > > > > > > > /d/o
> > > > > > > > > > > ptou
> > > > > > > > > > > t.
> > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > --
> > > > > > > > > You received this message because you are subscribed
> > > > > > > > > to
> > > > > > > > > the
> > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > emails
> > > > > > > > > from
> > > > > > > > > it,
> > > > > > > > > send an email to golang-nuts+unsubscribe@googlegroups
> > > > > > > > > .com
> > > > > > > > > .
> > > > > > > > > For more options, visit https://groups.google.com/d/o
> > > > > > > > > ptou
> > > > > > > > > t.
> > > > > > > > > 
> > > > > > > > > --
> > > > > > > > > You received this message because you are subscribed
> > > > > > > > > to
> > > > > > > > > the
> > > > > > > > > Google Groups "golang-nuts" group.
> > > > > > > > > To unsubscribe from this group and stop receiving
> > > > > > > > > emails
> > > > > > > > > from
> > > > > > > > > it,
> > > > > > > > > send an email to golang-nuts+unsubscribe@googlegroups
> > > > > > > > > .com
> > > > > > > > > .
> > > > > > > > > For more options, visit https://groups.google.com/d/o
> > > > > > > > > ptou
> > > > > > > > > t.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to