How to call a private protocol extension method from a public protocol extension method


(David Ungar) #1

I love protocol-oriented programming because of the guarantees that come with value types. But I cannot figure out how to do the same factoring I can do with the class side of the the language. I want to factor out common code into a public method that calls specific code in a private method & I want to do this for value types.

Here it is in classes:

public class CommonSuper {
  public func publicFn() { … specificPrivateFn() … }
  private func specificPrivateFn() { }
}

private class SubA {
  override private func specificPrivate() { … }
}
private class SubB {
  override private func specificPrivate() { … }
}

I have tried it lots of ways with protocols, and can get none to compile. Here is one:

public protocol PublicProto {
    func publicFn()
}

private protocol PrivateProto {
    func specificPrivateFn()
}

public extension PublicProto where Self: PrivateProto { // Error: Extension cannot be declared public because its generic requirement uses a private type
    public func publicFn() { specificPrivateFn() } // Error: Cannot declare a public instance method in an extension with private requirements
}

private struct SA: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}
private struct SB: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}

What am I doing wrong?

Thanks,

- David


(Kevin Greene) #2

You could have your common superclass implement your protocol. E.g...

public protocol PublicProto {

  func publicFn()

}

public class CommonSuper: PublicProto {

  public func publicFn() { specificPrivate() }

  private func specificPrivate() {}

}

private class SubA: CommonSuper {

  override private func specificPrivate() { /* ... */ }

}

private class SubB: CommonSuper {

  override private func specificPrivate() { /* ... */ }

}

I don't know what you're doing specifically, but I would guess that a
cleaner approach would likely be to get rid of the super class entirely,
and pull the shared logic from your two subclasses into a separate object
that both classes instantiate, or have injected. Then have your two classes
implement PublicProto directly. That discussion would probably be best had
on another mailing list though.

···

On Wed, Jun 22, 2016 at 11:19 AM, David Ungar via swift-users < swift-users@swift.org> wrote:

I love protocol-oriented programming because of the guarantees that come
with value types. But I cannot figure out how to do the same factoring I
can do with the class side of the the language. I want to factor out common
code into a public method that calls specific code in a private method & I
want to do this for value types.

Here it is in classes:

public class CommonSuper {
  public func publicFn() { … specificPrivateFn() … }
  private func specificPrivateFn() { }
}

private class SubA {
  override private func specificPrivate() { … }
}
private class SubB {
  override private func specificPrivate() { … }
}

I have tried it lots of ways with protocols, and can get none to compile.
Here is one:

public protocol PublicProto {
    func publicFn()
}

private protocol PrivateProto {
    func specificPrivateFn()
}

public extension PublicProto where Self: PrivateProto { // Error:
Extension cannot be declared public because its generic requirement uses a
private type
    public func publicFn() { specificPrivateFn() } // Error: Cannot
declare a public instance method in an extension with private requirements
}

private struct SA: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}
private struct SB: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}

What am I doing wrong?

Thanks,

- David

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(David Ungar) #3

Kevin,

Thank you so much for helping me out. I wasn’t clear, but I’m hoping to find a solution that uses only value types and protocols.

- David

···

On Jun 22, 2016, at 1:19 PM, Kevin Greene <kgreenek@gmail.com> wrote:

You could have your common superclass implement your protocol. E.g...

public protocol PublicProto {
  func publicFn()
}

public class CommonSuper: PublicProto {
  public func publicFn() { specificPrivate() }
  private func specificPrivate() {}
}

private class SubA: CommonSuper {
  override private func specificPrivate() { /* ... */ }
}

private class SubB: CommonSuper {
  override private func specificPrivate() { /* ... */ }
}

I don't know what you're doing specifically, but I would guess that a cleaner approach would likely be to get rid of the super class entirely, and pull the shared logic from your two subclasses into a separate object that both classes instantiate, or have injected. Then have your two classes implement PublicProto directly. That discussion would probably be best had on another mailing list though.

On Wed, Jun 22, 2016 at 11:19 AM, David Ungar via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
I love protocol-oriented programming because of the guarantees that come with value types. But I cannot figure out how to do the same factoring I can do with the class side of the the language. I want to factor out common code into a public method that calls specific code in a private method & I want to do this for value types.

Here it is in classes:

public class CommonSuper {
  public func publicFn() { … specificPrivateFn() … }
  private func specificPrivateFn() { }
}

private class SubA {
  override private func specificPrivate() { … }
}
private class SubB {
  override private func specificPrivate() { … }
}

I have tried it lots of ways with protocols, and can get none to compile. Here is one:

public protocol PublicProto {
    func publicFn()
}

private protocol PrivateProto {
    func specificPrivateFn()
}

public extension PublicProto where Self: PrivateProto { // Error: Extension cannot be declared public because its generic requirement uses a private type
    public func publicFn() { specificPrivateFn() } // Error: Cannot declare a public instance method in an extension with private requirements
}

private struct SA: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}
private struct SB: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}

What am I doing wrong?

Thanks,

- David

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Kevin Greene) #4

Oh gotcha. I totally misunderstood the question. Sorry about that!
I didn't actually realize you can extend protocols. Cool stuff! For anybody
else who is uninitiated:
https://www.raywenderlich.com/109156/introducing-protocol-oriented-programming-in-swift-2

···

On Wed, Jun 22, 2016 at 3:17 PM, David Ungar <ungar@mac.com> wrote:

Kevin,

Thank you so much for helping me out. I wasn’t clear, but I’m hoping to
find a solution that uses only value types and protocols.

- David

On Jun 22, 2016, at 1:19 PM, Kevin Greene <kgreenek@gmail.com> wrote:

You could have your common superclass implement your protocol. E.g...

public protocol PublicProto {
  func publicFn()
}

public class CommonSuper: PublicProto {
  public func publicFn() { specificPrivate() }
  private func specificPrivate() {}
}

private class SubA: CommonSuper {
  override private func specificPrivate() { /* ... */ }
}

private class SubB: CommonSuper {
  override private func specificPrivate() { /* ... */ }
}

I don't know what you're doing specifically, but I would guess that a
cleaner approach would likely be to get rid of the super class entirely,
and pull the shared logic from your two subclasses into a separate object
that both classes instantiate, or have injected. Then have your two classes
implement PublicProto directly. That discussion would probably be best had
on another mailing list though.

On Wed, Jun 22, 2016 at 11:19 AM, David Ungar via swift-users < > swift-users@swift.org> wrote:

I love protocol-oriented programming because of the guarantees that come
with value types. But I cannot figure out how to do the same factoring I
can do with the class side of the the language. I want to factor out common
code into a public method that calls specific code in a private method & I
want to do this for value types.

Here it is in classes:

public class CommonSuper {
  public func publicFn() { … specificPrivateFn() … }
  private func specificPrivateFn() { }
}

private class SubA {
  override private func specificPrivate() { … }
}
private class SubB {
  override private func specificPrivate() { … }
}

I have tried it lots of ways with protocols, and can get none to compile.
Here is one:

public protocol PublicProto {
    func publicFn()
}

private protocol PrivateProto {
    func specificPrivateFn()
}

public extension PublicProto where Self: PrivateProto { // Error:
Extension cannot be declared public because its generic requirement uses a
private type
    public func publicFn() { specificPrivateFn() } // Error: Cannot
declare a public instance method in an extension with private requirements
}

private struct SA: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}
private struct SB: PublicProto, PrivateProto {
    private func specificPrivateFn() {}
}

What am I doing wrong?

Thanks,

- David

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users