Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggest] class.md 「objectの apply メソッドとして定義することが多いです」の部分 #979

Open
rinotc opened this issue Aug 1, 2022 · 8 comments
Assignees

Comments

@rinotc
Copy link
Contributor

rinotc commented Aug 1, 2022

クラスの章の次の部分ですが

objectの apply メソッドとして定義することが多いです。

ちょっと思想入っちゃうかもですが、実務上はコンパニオンオブジェクトにstatic factoryとして複数の生成用のメソッドを提供することが多い(というか、綺麗にいく)かなと。

例があってるか分からないけど雰囲気

class Point(val x: Double, val y: Double) {
  ...
}

object Point {
  def apply(x: Double, y: Double) = new Point(x, y)

  def from(r: Double, theta: Double) = {
    val x = r * cos(theta)
    val y = r * sin(theta)
    new Point(x, y)
  }
}
@xuwei-k
Copy link
Contributor

xuwei-k commented Aug 1, 2022

そこの書き方どうするかもそうだけど、
そもそも書くなら、apply自体が省略して書ける仕様に関する、メリットやデメリットを説明するとか…? 🤔
メリットでもあるけど、あまりにも使い過ぎるとかえってわかりづらくなる?とかいう感じの

@rinotc
Copy link
Contributor Author

rinotc commented Aug 8, 2022

その辺ちょっと言語化したいですね。メリデメ草案考えてみます( ̄^ ̄)ゞ

@rinotc rinotc self-assigned this Aug 8, 2022
@kmizu
Copy link
Contributor

kmizu commented Aug 15, 2022

@rinotc

なるほど。

object Point {
  def apply(x: Double, y: Double) = new Point(x, y)

  def apply(r: Double, theta: Double) = {
    val x = r * cos(theta)
    val y = r * sin(theta)
    new Point(x, y)
  }
}

よりは(というより、このケースだとシグニチャ同じなのでコンパイルエラー)

object Point {
  def apply(x: Double, y: Double) = new Point(x, y)

  def from(r: Double, theta: Double) = {
    val x = r * cos(theta)
    val y = r * sin(theta)
    new Point(x, y)
  }
}

のほうがいいみたいな話でしょうか。オプションとして、後者もあるよみたいな書き方はどうでしょう。 cc @xuwei-k

@kmizu
Copy link
Contributor

kmizu commented Aug 15, 2022

@rinotc 記述例ですが、たとえば:

複数のオブジェクトの生成方法を提供したい場合、以下のどちらかの方法を使うことが多いです。

- コンパニオンオブジェクトのapplyメソッドを複数定義する(例も入れる)
- コンパニオンオブジェクトにfactoryメソッドを複数定義する(例もいれる)

みたいな感じとか?

@rinotc
Copy link
Contributor Author

rinotc commented Aug 15, 2022

@kmizu
そんな感じです!

複数生成方法を書きたい場合は、コンパニオンオブジェクトにstatic factory(いつもはこの用語で話してるけど正確かどうかは知らない)で生成方法を複数用意することが多いです的なイメージ?

@xuwei-k
Copy link
Contributor

xuwei-k commented Aug 15, 2022

理由を説明し出すと、そもそもそこの流れだと、コンストラクタの話の派生だから、なぜScalaではセカンダリーなコンストラクタ定義しない慣習なのか?とか、そっちもまず説明するのか???という話にもなる…? 🤔
現状でも嘘が書いてあるわけでもないので、文法だけ簡潔に説明して、詳細な慣習の理由に(少なくともここで)深入りしない、みたいな方針にするなら、今のままでもバランスは取れているといえなくもない 🤔

追記改善することを否定したいわけでもないが、そういう細かいこと考え出すと難しいな、と思うけど、まぁ最終的には任せます

@xuwei-k
Copy link
Contributor

xuwei-k commented Aug 15, 2022

若干話逸れる?けど、Scala 3で良くも悪くも呼び出し時にnewが省略出来るのも関連しなくもないな

@rinotc
Copy link
Contributor Author

rinotc commented Aug 15, 2022

単純に、


コンパニオンオブジェクトにfactoryメソッドとして複数提供することが多いです。

object Point {

  // applyで定義した場合はnewなしで、Point(1, 3)のような形でかけます // <-- これはどこか説明してるところを書くでいいかも。
  def apply(...) = ...

  def from(...) = ...
}

みたいにしようかなと思ってます。applyのオーバーロードを示唆するでもなく、かといってファクトリごとにメソッドを分けることを示唆するでもなく。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants