0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

fluorite-7 日本語チュートリアル Part 9 オブジェクト

Last updated at Posted at 2020-06-21

チュートリアルトップ

←前回 次回→

このパートでは、文字列と値の組であるオブジェクトについて取り扱います。

レッスン1 オブジェクト

fluorite-7において、オブジェクトとは文字列から値を引くことができる辞書です。
何も定義されていない空のオブジェクトを作るには、{}と記述します。
この演算子を、オブジェクト初期化子と呼びます。

$ fl7 '{}'
{}

レッスン2 プロパティの宣言

{}の間で「キー:」と記述することでプロパティ宣言できます。

$ fl7 '{a: 10}'
{a:10}

プロパティは;で区切ることで複数宣言できます。
;は無駄に大量に並べても、単に無視されます。

$ fl7 '{a: 10; b: 200}'
{a:10;b:200}

$ fl7 '{;;;a: 10;;; b: 200;;;}'
{a:10;b:200}

キーに識別子を書いた場合はその識別子の名前がキーになりますが、そうでない場合はその式が評価されてキーとなります。

$ fl7 '{"#": 10}'
{#:10}

$ fl7 '{"a" & "b": 10}'
{ab:10}

$ fl7 'k: "a"; {(k): 10}'
{a:10}

レッスン3 プロパティへのアクセス

「オブジェクト.識別子」もしくは「オブジェクト[文字列]」でオブジェクトのプロパティにアクセスします。

$ fl7 '{a: 10; b: 200}.b'
200

$ fl7 '{a: 10; b: 200}["b"]'
200

[ ]によるアクセスは文字列であることに気を付けてください。
その場所に識別子を書いたとき、その名前が既に使用済みであれば、その名前が示す値がキーとして使われます。

$ fl7 'a: "b"; {a: 10; b: 200}[a]'
200

また、「オブジェクト."キー"」のように書くと、こちらでも文字列による指定ができます。

$ fl7 '{ab: 10}.ab'
10

$ fl7 '{ab: 10}."ab"'
10

$ fl7 '{ab: 10}.("a" & "b")'
10

存在しないキーにアクセスすると、NULLが返されます。

$ fl7 '{a: 10}.b'
NULL

レッスン4 オブジェクトの継承

fluorite-7のオブジェクトは継承することができます。
継承するには、「オブジェクト{ }」と記述します。
継承したオブジェクトに対して.でアクセスをすると、親オブジェクトのプロパティも見えるようになります。

$ fl7 '{a: 10}{b: 200}.a'
10

親オブジェクトと同じ名前のプロパティがあった場合は、子オブジェクトのプロパティが優先されます。

$ fl7 '{a: 10}{a: 200}.a'
200

一方、[ ]によるアクセスは継承を考慮しません。

$ fl7 '{a: 10}{b: 200}["a"]'
NULL

継承を考慮したプロパティのアクセスをメンバアクセス.メンバアクセス演算子と呼びます。

レッスン5 オブジェクトのストリーマ展開

オブジェクトをストリーマ展開すると、そのオブジェクトのプロパティのストリーマが得られます。
親オブジェクトのプロパティは参照しません。

$ fl7 '{a: 10}{b: 200; c: 4}[]'
{key:b;value:200}
{key:c;value:4}

レッスン6 オブジェクトの文字列化

オブジェクトを文字列化すると、継承を無視したプロパティの一覧が得られます。

$ fl7 '&{a: 10}{b: 200; c: 4}'
{b:200;c:4}

レッスン7 プロパティのストリーマからのオブジェクト構築

演算子{[ ]}は、プロパティのストリーマからオブジェクトを構築します。

$ fl7 '{[ {key:A;value:B},{key:C;value:D} ]}'
{A:B;C:D}

丁度ストリーマ展開と逆の操作です。

レッスン8 宣言されたプロパティへの参照

オブジェクト初期化子の中で「識別子:」によって定義されたプロパティは、そのオブジェクト初期化子の中から名前で呼べるようになります。

$ fl7 '{y: x * 20; x: 3; z: x + y}'
{y:60;x:3;z:63}

整形してみましょう。

{
  y: x * 20;
  x: 3;
  z: x + y;
}

見ての通り、yの値はxに依存し、zの値はxyに依存します。
このプロパティはxyzの順番でセットしなければなりませんが、実際そのような順番でセットされます。

オブジェクト初期化子がオブジェクトを初期化する過程において、この依存関係は循環してはなりません。
例えば次のようなものは循環が起こります。

$ fl7 '{x: x}'

xを初期化するにはxが必要ですが、そのxを初期化するためにxが必要です。


オブジェクト初期化子がオブジェクトを初期化する過程において、この依存関係は循環してはなりません。

しかし、「オブジェクトを初期化する過程」でなければ循環してもかまいません。

$ fl7 '{f: () -> f}'
{f:[FluoriteFunction]}

これは評価すると関数fが返ってくる関数fが定義されたオブジェクトです。
このように名前の参照が遅延される場合であれば、自由に名前を利用することができます。

レッスン9 プロパティ初期化における代入と即席代入

オブジェクト初期化子の中でプロパティが名前で直接呼べるようになることは、良いことばかりではありません。
既存の変数と同名のプロパティを作る状況はよくあることです。

そういう状況の為に、代入というプロパティ初期化の方法があります。
代入によるプロパティ初期化を行うには、:の代わりに=を使用します。

$ fl7 'x: 5; {x = x}'
{x:5}

x: xでは循環参照のエラーになっていたものが、x = xでは正しくxというキーに変数xの中身がセットされました。

更に、値部分が1個の識別子のみで、キーがその識別子と同じ場合、即席代入を使うことができます。
即席代入は、もはや=も書かず、単にその識別子を記述するだけです。

$ fl7 'x: 5; {x}'
{x:5}

$ fl7 'p: k, v -> {k; v}; p("a"; 50)'
{k:a;v:50}

まとめ

  • { }でオブジェクトを作る。
  • key: valueでプロパティを宣言。
  • プロパティは;で区切って複数初期化できる。
  • object{}で継承つきオブジェクトを生成。
  • object.identifierでメンバアクセス。
  • メンバアクセスは継承を考慮する。
  • object[string]で通常のプロパティアクセス。
  • object[]でプロパティのストリーマを得る。
  • {[ ]}でプロパティのストリーマから構築。
  • key = valueはプロパティの代入。
  • identifierはプロパティの即席代入。
  • キーが識別子の宣言は、同じオブジェクト初期化子の中から名前で呼べるようになる。
  • オブジェクト初期化時に依存関係が循環するように名前を参照することはできない。

Part 10

次回→

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?