Global variables in Ruby

Trong Ruby có khá nhiều biến global đã được định nghĩa trước, tuy nhiên chắc hẳn không nhiều trong chúng ta biết và dùng đến. Ở bài viết này mình xin giới thiệu với các bạn 1 số biến global hữu ích trong Ruby.

Các biến global có tên mang ý nghĩa rõ ràng

$DEBUG

Giá trị của debugging flag (true nếu chạy ruby với option -d hoặc --debug)

# test.rb
puts $DEBUG
$ ruby test.rb
false

$ ruby -d test.rb
true

$VERBOSE

Giá trị của verbose flag (true nếu chạy ruby với option -v hoặc --verbose)

# test.rb
puts $VERBOSE
$ ruby test.rb
false

$ ruby -v test.rb
true

$FILENAME

Tên của file đang được đọc từ ARGF (bằng với ARGF.filename)

# test.rb
ARGF.each { puts $FILENAME; ARGF.skip }
$ ruby test.rb input1.txt input2.txt input3.txt
input1.txt
input2.txt
input3.txt

$LOAD_PATH

Những thư mục mà code Ruby trong đó sẽ được load. Ví dụ khi /some/path/ruby đã được thêm vào load path thì chúng ta có thể dùng

require 'script'

thay cho

require '/some/path/ruby/script.rb'

$stderr

Standard error output

irb(main):001:0> $stderr
=> #<IO:<STDERR>>

$stdin

Standard input

irb(main):002:0> $stdin
=> #<IO:<STDIN>>

$stdout

Standard output

irb(main):003:0> $stdout
=> #<IO:<STDOUT>>

Các biến global liên quan đến exception

$!

Exception object vừa được raise (cũng có thể access object này bằng => trong mệnh đề rescue)

irb(main):001:0> begin
irb(main):002:1*   1/0
irb(main):003:1> rescue
irb(main):004:1>   $!
irb(main):005:1> end
=> #<ZeroDivisionError: divided by 0>

[email protected]

Backtrace của exception vừa được raise

irb(main):001:0> begin
irb(main):002:1*   1/0
irb(main):003:1> rescue
irb(main):004:1>   [email protected]
irb(main):005:1> end
=> ["(irb):2:in `/'", "(irb):2:in `irb_binding'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/workspace.rb:87:in `eval'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/workspace.rb:87:in `evaluate'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/context.rb:381:in `evaluate'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:493:in `block (2 levels) in eval_input'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:627:in `signal_status'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:490:in `block in eval_input'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/ruby-lex.rb:246:in `block (2 levels) in each_top_level_statement'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/ruby-lex.rb:232:in `loop'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/ruby-lex.rb:232:in `block in each_top_level_statement'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/ruby-lex.rb:231:in `catch'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb/ruby-lex.rb:231:in `each_top_level_statement'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:489:in `eval_input'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:430:in `block in run'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:429:in `catch'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:429:in `run'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/lib/ruby/2.4.0/irb.rb:385:in `start'", "/Users/tungnd/.rvm/rubies/ruby-2.4.2/bin/irb:11:in `<main>'"]

Các biến global liên quan đến regular expression

$~

Object MatchData là kết quả của phép match regex gần nhất

irb(main):001:0> "hello world" =~ /[a-z]+/
=> 0
irb(main):002:0> $~
=> #<MatchData "hello">

$&

String vừa match với regex (tương đương với m[0] với m là 1 object MatchData)

irb(main):001:0> "hello world" =~ /[a-z]+/
=> 0
irb(main):002:0> $&
=> "hello"
irb(main):003:0> m = "hello world".match(/[a-z]+/)
=> #<MatchData "hello">
irb(main):004:0> m[0]
=> "hello"

$`

String ở bên trái string vừa match với regex (tương đương với m.pre_match với m là 1 object MatchData)

irb(main):001:0> "hello world" =~ /world/
=> 6
irb(main):002:0> $`
=> "hello "
irb(main):003:0> m = "hello world".match(/world/)
=> #<MatchData "world">
irb(main):004:0> m.pre_match
=> "hello "

$'

String ở bên phải string vừa match với regex (tương đương với m.post_match với m là 1 object MatchData)

irb(main):001:0> "hello world" =~ /hello/
=> 0
irb(main):002:0> $'
=> " world"
irb(main):003:0> m = "hello world".match(/hello/)
=> #<MatchData "hello">
irb(main):004:0> m.post_match
=> " world"

$1, $2, $3, ...

Các string match với group thứ 1, 2, 3, ... trong phép match gần nhất

irb(main):001:0> "123456789" =~ /(1)(2)(3)(4)(5)(6)(7)(8)(9)/
=> 0
irb(main):002:0> $1
=> "1"
irb(main):003:0> $2
=> "2"
irb(main):004:0> $3
=> "3"

$+

String match với group cuối cùng trong phép match gần nhất

irb(main):001:0> "123456789" =~ /(1)(2)(3)(4)(5)(6)(7)(8)(9)/
=> 0
irb(main):002:0> $+
=> "9"

Các biến global liên quan đến IO

$/

Input record separator (giá trị mặc định là newline \n), dùng cho các method gets, readline, ...

irb(main):001:0> $/
=> "\n"
irb(main):002:0> gets
hello
=> "hello\n"
irb(main):003:0> $/ = "END"
=> "END"
irb(main):004:0> gets
hello
world
END
=> "hello\nworld\nEND"

$\

Output record separator khi dùng method print hoặc IO#write (giá trị mặc định là nil)

irb(main):001:0> p $\
nil
=> nil
irb(main):002:0> print "hello"
hello=> nil
irb(main):003:0> $\ = "END"
=> "END"
irb(main):004:0> p $\
"END"
=> "END"
irb(main):005:0> print "hello"
helloEND=> nil

$,

Output field separator khi dùng method print (giá trị mặc định là nil)

irb(main):001:0> p $,
nil
=> nil
irb(main):002:0> print 1, 2, 3
123=> nil
irb(main):003:0> $, = ","
=> ","
irb(main):004:0> print 1, 2, 3
1,2,3=> nil

Đây cũng là default separator khi dùng method Array#join

irb(main):001:0> p $,
nil
=> nil
irb(main):002:0> puts [1,2,3].join
123
=> nil
irb(main):003:0> $, = ","
=> ","
irb(main):004:0> puts [1,2,3].join
1,2,3
=> nil

$;

Default separator khi dùng method String#split (giá trị mặc định là nil)

irb(main):001:0> p $;
nil
=> nil
irb(main):002:0> "1,2,3".split
=> ["1,2,3"]
irb(main):003:0> $; = ","
=> ","
irb(main):004:0> "1,2,3".split
=> ["1", "2", "3"]

$.

Số dòng hiện tại của file đang được đọc

$ cat input.txt 
1
2
3
irb(main):001:0> f = File.open 'input.txt', 'r'
=> #<File:input.txt>
irb(main):002:0> f.readline
=> "1\n"
irb(main):003:0> $.
=> 1
irb(main):004:0> f.readline
=> "2\n"
irb(main):005:0> $.
=> 2
...

$_

Nội dung dòng cuối cùng vừa được đọc

$ cat input.txt 
1
2
3
irb(main):001:0> f = File.open 'input.txt', 'r'
=> #<File:input.txt>
irb(main):002:0> $_
=> nil
irb(main):003:0> f.readline
=> "1\n"
irb(main):004:0> $_
=> "1\n"
irb(main):005:0> f.readline
=> "2\n"
irb(main):006:0> $_
=> "2\n"
...

$<

Bằng với ARGF

# test.rb
$<.each { puts $<.filename; $<.skip }
$ ruby test.rb input1.txt input2.txt input3.txt
input1.txt
input2.txt
input3.txt

$>

Output mặc định của print, printf (giá trị mặc định là $stdout)

irb(main):001:0> $>
=> #<IO:<STDOUT>>

Các biến global khác

$0

Tên của script đang được thực thi

# test.rb
puts $0
$ ruby test.rb
test.rb

$$

Process number của tiến trình Ruby đang chạy script hiện tại

# test.rb
puts $$
$ ruby test.rb
12345

$?

Status của child process cuối cùng được chạy

irb(main):001:0> `pwd`
=> "/Users/tungnd\n"
irb(main):002:0> $?
=> #<Process::Status: pid 12345 exit 0>

$:

Bằng với $LOAD_PATH

$"

Mảng chứa các module đã được require

References

  1. http://www.tutorialspoint.com/ruby/ruby_predefined_variables.htm
  2. http://docs.huihoo.com/ruby/ruby-man-1.4/variable.html#equal