erg/doc/EN/tips.md
Shunsuke Shibayama 8badf02f39 Update docs
2022-11-27 17:46:14 +09:00

2.9 KiB

Tips

Want to change the language in which errors are displayed

Please download Erg for your language. However, external libraries may not support multiple languages.

Want to change only certain attributes of a record

record: {.name = Str; .age = Nat; .height = CentiMeter}
{height; ...rest} = record
mut_record = {.height = !height; ...rest}

Want to shadow variables

Shadowing in the same scope is not possible with Erg. However, you can redefine them if the scope changes (This is a syntax called instance block).

## Get a T!-type object and finally assign it to a variable as type T
x: T =
    x: T! = foo()
    x.bar!()
    x.freeze()

Want to reuse a final class (non-inheritable class) somehow

You can create a wrapper class. This is a so-called composition pattern.

FinalWrapper = Class {inner = FinalClass}
FinalWrapper.
    method self =
        self::inner.method()
    ...

Want to use an enumerated type that is not a string

You can define a traditional enumerated type (algebraic data type) commonly found in other languages as follows If you implement Singleton, classes and instances are identical. Also, if you use Enum, the type of choice is automatically defined as a redirect attribute.

Ok = Class Impl := Singleton
Err = Class Impl := Singleton
ErrWithInfo = Inherit {info = Str}
Status = Enum Ok, Err, ErrWithInfo
stat: Status = Status.new ErrWithInfo.new {info = "error caused by ..."}
match! stat:
    Status.Ok -> ...
    Status.Err -> ...
    Status.ErrWithInfo::{info} -> ...
Status = Enum Ok, Err, ErrWithInfo
# is equivalent to
Status = Class Ok or Err or ErrWithInfo
Status.
    Ok = Ok
    Err = Err
    ErrWithInfo = ErrWithInfo

I want to enumerate at the beginning of 1

method 1:

arr = [...]
for! arr.iter().enumerate(start := 1), i =>
    ...

method 2:

arr = [...]
for! arr.iter().zip(1...) , i =>
    ...

Want to test a (white box) non-public API

The private API in foo.er is specially accessible in the module foo.test.er. The foo.test.er module cannot be imported, so it remains hidden.

# foo.er
private x = ...
# foo.test.er
foo = import "foo"

@Test
'testing private' x =
    ...
    y = foo::private x
    ...

Want to define a (variable) attribute that is read-only from the outside

You can make the attribute private and define a getter.

C = Class {v = Int!}
C::
    inc_v!(ref! self) = self::v.inc!()
    ...
C.
    get_v(ref self): Int = self::v.freeze()
    ...

When implementing a trait's methods, warnings are given for variables that were not used

You can use discard.

T = Trait {.f = (Self, x: Int, s: Str) -> Int}

C = Class T
C|<: T|.
    f self, x, s =
        discard s
        ...

Want to stop warnings

There is no option in Erg to stop warnings (this is by design). Please rewrite your code.