Class: Gemite::Environment

Inherits:
Object
  • Object
show all
Defined in:
lib/gemite/environment.rb

Overview

変数を保持するスコープ。

スコープ規則(仕様25):

- グローバル変数はファイル単位 -> ルートのEnvironment(boundary:false, parent:nil)を
ファイル実行全体(<?gemite ?>ブロックをまたいでも)で共有する。
- 関数内変数はローカル -> 関数呼び出し時に boundary: true の新しい環境を作る。
assign(代入)はこの境界を越えて外側を書き換えない。ただし読み取り(get)は
外側(クロージャ)を辿れる。
- @forのループ変数はループ内のみ有効 -> こちらはEnvironmentを増やさず、
Interpreter側でループ変数名だけ退避/削除することで実現する(他の代入は
通常通り現在のスコープに作用する)。

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent: nil, boundary: false) ⇒ Environment

Returns a new instance of Environment.



18
19
20
21
22
# File 'lib/gemite/environment.rb', line 18

def initialize(parent: nil, boundary: false)
  @vars = {}
  @parent = parent
  @boundary = boundary
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



16
17
18
# File 'lib/gemite/environment.rb', line 16

def parent
  @parent
end

Instance Method Details

#assign(name, value) ⇒ Object

一般的な代入。既存の束縛が(関数境界を越えない範囲で)見つかればそこを更新し、 見つからなければ現在のスコープに新規作成する。



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/gemite/environment.rb', line 46

def assign(name, value)
  env = self
  loop do
    if env.has_local?(name)
      env.set_local(name, value)
      return value
    end
    break if env.boundary? || env.parent.nil?

    env = env.parent
  end
  set_local(name, value)
  value
end

#boundary?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/gemite/environment.rb', line 24

def boundary?
  @boundary
end

#delete_local(name) ⇒ Object



40
41
42
# File 'lib/gemite/environment.rb', line 40

def delete_local(name)
  @vars.delete(name)
end

#get(name) ⇒ Object

変数の読み取り。関数境界を越えて外側(クロージャ)を辿る。 未定義の変数は nil (寛容な設計。GET/POST同様に「存在しなければnil」に統一)。



63
64
65
66
67
68
69
70
71
# File 'lib/gemite/environment.rb', line 63

def get(name)
  env = self
  while env
    return env.get_local(name) if env.has_local?(name)

    env = env.parent
  end
  nil
end

#get_local(name) ⇒ Object



32
33
34
# File 'lib/gemite/environment.rb', line 32

def get_local(name)
  @vars[name]
end

#has_local?(name) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/gemite/environment.rb', line 28

def has_local?(name)
  @vars.key?(name)
end

#set_local(name, value) ⇒ Object



36
37
38
# File 'lib/gemite/environment.rb', line 36

def set_local(name, value)
  @vars[name] = value
end