erg/doc/JA/tips.md
2023-02-08 20:28:17 +08:00

111 lines
3 KiB
Markdown

# Tips
[![badge](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com%2Fdefault%2Fsource_up_to_date%3Fowner%3Derg-lang%26repos%3Derg%26ref%3Dmain%26path%3Ddoc/EN/tips.md%26commit_hash%3D8673a0ce564fd282d0ca586642fa7f002e8a3c50)](https://gezf7g7pd5.execute-api.ap-northeast-1.amazonaws.com/default/source_up_to_date?owner=erg-lang&repos=erg&ref=main&path=doc/EN/tips.md&commit_hash=8673a0ce564fd282d0ca586642fa7f002e8a3c50)
## エラーの表示言語を変えたい
各国語版のergをダウンロードしてください。
ただし、標準ライブラリ以外では多言語対応がなされていない可能性があります。
## レコードの特定の属性だけ可変化したい
```python
record: {.name = Str; .age = Nat; .height = CentiMeter}
{height; *rest} = record
mut_record = {.height = !height; *rest}
```
## 変数のシャドーイングがしたい
Ergで同一スコープ内でのシャドーイングはできません。しかし、スコープが変われば定義しなおせるので、インスタントブロックを使うといいでしょう。
```python
# T!型オブジェクトを取得し、最終的にT型として変数へ代入する
x: T =
x: T! = foo()
x.bar!()
x.freeze()
```
## final class(継承不能クラス)を何とかして再利用したい
ラッパークラスを作りましょう。これはいわゆるコンポジション(合成)と言われるパターンです。
```python
FinalWrapper = Class {inner = FinalClass}
FinalWrapper.
method self =
self::inner.method()
...
```
## 1始まりでenumerateしたい
method 1:
```python
arr = [...]
for! arr.iter().enumerate(start := 1), i =>
...
```
method 2:
```python
arr = [...]
for! arr.iter().zip(1..), i =>
...
```
## 非公開APIを(ホワイトボックス)テストしたい
`foo.er`の非公開APIは`foo.test.er`というモジュールでは特別にアクセス可能となります。
`foo.test.er`モジュールはインポートできないので、隠蔽性は保たれます。
```python
# foo.er
private x = ...
```
```python
# foo.test.er
foo = import "foo"
@Test
'testing private' x =
...
y = foo::private x
...
```
## 外部からはread-onlyな(可変)属性を定義したい
属性をプライベートにして、ゲッタを定義するとよいでしょう。
```python
C = Class {v = Int!}
C::
inc_v!(ref! self) = self::v.inc!()
...
C.
get_v(ref self): Int = self::v.freeze()
...
```
## トレイトのメソッドを実装する際に、使わなかった変数の警告が出る
`discard`または`_ = ...`を使うとよいでしょう。
```python
T = Trait {.f = (Self, x: Int, s: Str) -> Int}
C = Class T
C|<: T|.
f self, x, s =
discard s # or _ = s
...
```
## 警告を出さないようにしたい
Ergに警告を止めるオプションはありません(これは意図的な設計です)。コードを修正してください。