mirror of
https://github.com/mistergibson/gxg-web-client.git
synced 2026-08-15 03:26:00 -07:00
159 lines
3.8 KiB
Ruby
159 lines
3.8 KiB
Ruby
##
|
|
# Stores global variables and global variable aliases.
|
|
|
|
module Rubinius
|
|
class GlobalVariables
|
|
def initialize
|
|
load_path = CoreDB.load_path
|
|
loaded_features = CoreDB.loaded_features
|
|
|
|
@internal = LookupTable.new
|
|
|
|
@internal[:$;] = nil
|
|
@internal[:$/] = "\n" # Input record separator
|
|
@internal[:$\] = nil # Output record separator
|
|
@internal[:$<] = ARGF
|
|
@internal[:$:] = load_path
|
|
@internal[:$-I] = load_path
|
|
@internal[:$"] = loaded_features
|
|
@internal[:$,] = nil # Output field separator
|
|
@internal[:$.] = 0
|
|
@internal[:$=] = false # ignore case, whatever that is
|
|
@internal[:$0] = nil
|
|
@internal[:$CONSOLE] = STDOUT
|
|
@internal[:$DEBUG] = false
|
|
@internal[:$LOADED_FEATURES] = loaded_features
|
|
@internal[:$LOAD_PATH] = load_path
|
|
@internal[:$SAFE] = 0
|
|
|
|
@internal[:$stderr] = STDERR
|
|
@internal[:$stdin] = STDIN
|
|
@internal[:$stdout] = STDOUT
|
|
|
|
@alias = LookupTable.new
|
|
@hooks = LookupTable.new
|
|
end
|
|
|
|
private :initialize
|
|
|
|
def key?(key)
|
|
@internal.key?(key) || @alias.key?(key)
|
|
end
|
|
|
|
def variables
|
|
@internal.keys + @alias.keys
|
|
end
|
|
|
|
def [](key)
|
|
if @internal.key? key
|
|
@internal[key]
|
|
elsif @hooks.key? key
|
|
@hooks[key][0].call(key)
|
|
elsif @alias.key? key
|
|
self[@alias[key]]
|
|
end
|
|
end
|
|
|
|
def []=(key, data)
|
|
if alias_key = @alias[key]
|
|
self[alias_key] = data
|
|
elsif @hooks.key? key
|
|
hook = @hooks[key]
|
|
val = hook[1].call(key, data)
|
|
if hook[2]
|
|
@internal[key] = val
|
|
end
|
|
val
|
|
else
|
|
@internal[key] = data
|
|
end
|
|
end
|
|
|
|
# Respects internal and alias, but not hooks. Useful to bypass
|
|
# normal read only checks.
|
|
def set!(key, data)
|
|
if alias_key = @alias[key]
|
|
set! alias_key, data
|
|
else
|
|
@internal[key] = data
|
|
end
|
|
end
|
|
|
|
def add_alias(current_name, alias_name)
|
|
current_name = current_name.to_sym
|
|
alias_name = alias_name.to_sym
|
|
|
|
if @internal.key? alias_name
|
|
@internal.delete alias_name
|
|
end
|
|
|
|
if @hooks.key? alias_name
|
|
@hooks.delete alias_name
|
|
end
|
|
|
|
@alias[alias_name] = current_name
|
|
end
|
|
|
|
def illegal_set(*args)
|
|
raise NameError, "unable to set global"
|
|
end
|
|
|
|
def set_hook(var, getter=nil, setter=nil, &block)
|
|
if block
|
|
if getter or setter
|
|
raise ArgumentError, "duplicate procs provided with block"
|
|
end
|
|
|
|
@hooks[var] = [block, method(:illegal_set)]
|
|
else
|
|
set_internal = false
|
|
set_internal = true if getter == :[]
|
|
|
|
if !getter
|
|
getter = method(:nil_return)
|
|
elsif getter.kind_of? Symbol
|
|
getter = method(getter)
|
|
end
|
|
|
|
unless getter.respond_to?(:call)
|
|
raise ArgumentError, "getter must respond to call"
|
|
end
|
|
|
|
if !setter
|
|
setter = method(:illegal_set)
|
|
elsif setter.kind_of? Symbol
|
|
setter = method(setter)
|
|
end
|
|
|
|
unless setter.respond_to?(:call)
|
|
raise ArgumentError, "setter must respond to call"
|
|
end
|
|
|
|
@hooks[var] = [getter, setter, set_internal]
|
|
end
|
|
end
|
|
|
|
def remove_hook(var)
|
|
@hooks.delete(var)
|
|
end
|
|
|
|
def nil_return
|
|
nil
|
|
end
|
|
|
|
def set_filter(var, block)
|
|
@hooks[var] = [method(:nil_return), block, true]
|
|
end
|
|
|
|
def raise_readonly(key, data)
|
|
raise NameError, "#{key} is a read-only global variable"
|
|
end
|
|
|
|
def read_only(*vars)
|
|
mo = method(:raise_readonly)
|
|
vars.each do |v|
|
|
set_filter v, mo
|
|
end
|
|
end
|
|
end
|
|
end
|