syntax/special_globals.rb
tests/_examples/syntax/special_globals.rb in the metorex repository.
# What assigning a special global checks and stores, the aliases the
# command-line switches give some of them, and the names that cannot be
# assigned at all.
def refusal(code)
eval(code)
:assigned
rescue TypeError, NameError, ArgumentError => error
[error.class, error.message]
end
p(refusal("$~ = Object.new"))
p(refusal("$stdout = nil"))
p(refusal("$! = 1"))
p(refusal("$FILENAME = 'name'"))
p(refusal("$/ = 1"))
p(refusal("$-0 = 1"))
p(refusal("$0 = nil"))
p(refusal("$. = nil"))
p(refusal("$@ = []"))
old_separator = $/
tagged = Class.new(String).new("line")
$/ = tagged
p([$/.class, $/.frozen?, $/ == tagged])
frozen = "end".freeze
$/ = frozen
p($/.equal?(frozen))
$/ = old_separator
old_line_number = $.
$. = 12.5
p($.)
counter = Object.new
def counter.to_int
7
end
$. = counter
p($.)
$. = old_line_number
old_verbose = $VERBOSE
$VERBOSE = 1
p($VERBOSE)
$VERBOSE = old_verbose
p([$-0.equal?($/), $-I.equal?($:), $-w == $VERBOSE, $-d == $DEBUG])
begin
raise "broken"
rescue => error
$@ = ["here:1"]
p(error.backtrace)
end
["nil = 1", "true = 1", "false = 1", "self = 1", "$& = 1", "$1 = 1"].each do |code|
begin
eval(code)
rescue SyntaxError => error
p(error.message[/Can't [^\n]*/])
end
end
alias $matched_text $&
p(refusal("$matched_text = 'x'"))
"lamp".dup.force_encoding(Encoding::ISO_8859_1) =~ /(m)/
p([$&.encoding, $`.encoding, $'.encoding, $1.encoding])
outer = StandardError.new("outer")
inner = StandardError.new("inner")
seen = []
begin
begin
raise outer
rescue
raise inner
ensure
seen << $!
end
rescue
seen << $!
end
p(seen.map(&:message))
$_ = "main line"
Thread.new { $_ = "thread line" }.join
p($_)
kind, path = $LOAD_PATH.resolve_feature_path("pp")
p([kind, File.basename(path)])
p($LOAD_PATH.resolve_feature_path("no_such_feature"))
held = +"text"
held.instance_variable_set(:@mark, 1)
p([held.instance_variable_defined?(:@mark), held.instance_variable_defined?(:@other)])
warned = []
collector = Object.new
collector.define_singleton_method(:write) { |text| warned << text }
old_stderr = $stderr
$stderr = collector
old_deprecated = Warning[:deprecated]
Warning[:deprecated] = true
$VERBOSE = false
read = $=
$= = true
$, = ","
$, = nil
Warning[:deprecated] = old_deprecated
$VERBOSE = old_verbose
$stderr = old_stderr
p(warned.map { |text| text.sub(/\A.*warning: /, "") })
Output:
[TypeError, "wrong argument type Object (expected MatchData)"]
[TypeError, "$stdout must have write method, NilClass given"]
[NameError, "$! is a read-only variable"]
[NameError, "$FILENAME is a read-only variable"]
[TypeError, "value of $/ must be String"]
[TypeError, "value of $-0 must be String"]
[TypeError, "no implicit conversion of nil into String"]
[TypeError, "no implicit conversion from nil to integer"]
[ArgumentError, "$! not set"]
[String, true, true]
true
12
7
true
[true, true, true, true]
["here:1"]
"Can't assign to nil"
"Can't assign to true"
"Can't assign to false"
"Can't change the value of self"
"Can't set variable $&"
"Can't set variable $1"
[NameError, "$matched_text is a read-only variable"]
[#<Encoding:ISO-8859-1>, #<Encoding:ISO-8859-1>, #<Encoding:ISO-8859-1>, #<Encoding:ISO-8859-1>]
["inner", "inner"]
"main line"
[:rb, "pp.rb"]
nil
[true, false]
["variable $= is no longer effective\n", "variable $= is no longer effective; ignored\n", "non-nil '$,' is deprecated\n"]