12/08/2018, 16:46

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 ...

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>

$@

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>   $@
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 ), dùng cho các method gets, readline, ...

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

$

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
"
irb(main):003:0> $.
=> 1
irb(main):004:0> f.readline
=> "2
"
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
"
irb(main):004:0> $_
=> "1
"
irb(main):005:0> f.readline
=> "2
"
irb(main):006:0> $_
=> "2
"
...

$<

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
"
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
0