Ruby ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด 2.7.0 ๋ฆด๋ฆฌ์Šค

XNUMX๋…„์˜ ๊ฐœ๋ฐœ ๋์— ์ถœํŒ ๋œ ์„๋ฐฉํ•˜๋‹ค ๋ฃจ๋น„ 2.7.0, ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ์— ๋งค์šฐ โ€‹โ€‹ํšจ์œจ์ ์ด๊ณ  Perl, Java, Python, Smalltalk, ์—ํŽ , Ada ๋ฐ Lisp์˜ ์ตœ๊ณ ์˜ ๊ธฐ๋Šฅ์„ ํ†ตํ•ฉํ•˜๋Š” ๋™์  ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์ฝ”๋“œ๋Š” BSD("2-clause BSDL") ๋ฐ "Ruby" ๋ผ์ด์„ ์Šค์— ๋”ฐ๋ผ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” GPL ๋ผ์ด์„ ์Šค์˜ ์ตœ์‹  ๋ฒ„์ „์„ ์˜๋ฏธํ•˜๋ฉฐ GPLv3๊ณผ ์™„๋ฒฝํ•˜๊ฒŒ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. Ruby 2.7์€ ๊ธฐ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด 2๋…„์„ ํ• ๋‹นํ•˜๊ณ  3~XNUMX๊ฐœ์›”์˜ ํŒจ์น˜ ๋ฆด๋ฆฌ์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ๊ณ„ํš๋œ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์˜ ์ผ๋ถ€๋กœ ์ œ์ž‘๋  ์ผ๊ณฑ ๋ฒˆ์งธ ์ฃผ์š” ๋ฆด๋ฆฌ์Šค์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ๊ฐœ๋Ÿ‰:

  • ์‹คํ—˜์  ์ง€์› ํŒจํ„ด ๋งค์นญ(ํŒจํ„ด ๋งค์นญ) ์ฃผ์–ด์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ํŒจํ„ด ์ผ์น˜๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ’์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

    ์ผ€์ด์Šค [0, [1, 2, 3]] in [a, [b, *c]] pa #=> 0
    pb #=> 1
    pc #=> [2, 3] ๋

    ๊ฒฝ์šฐ {a: 0, b: 1}
    {a:0,x:1}์—์„œ
    :์ ‘๊ทผ๋ถˆ๊ฐ€
    {a: 0, b: var}์—์„œ
    p ๋ณ€์ˆ˜ #=> 1
    end

  • ๋Œ€ํ™”ํ˜• ๊ณ„์‚ฐ irb(REPL, Read-Eval-Print-Loop) ์‰˜์—๋Š” ์ด์ œ readline ํ˜ธํ™˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋œ ์—ฌ๋Ÿฌ ์ค„ ํŽธ์ง‘์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ผ ์ธ๋ฃจ๋น„๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. rdoc์— ๋Œ€ํ•œ ์ง€์›์ด ํ†ตํ•ฉ๋˜์–ด irb์˜ ์ง€์ •๋œ ํด๋ž˜์Šค, ๋ชจ๋“ˆ ๋ฐ ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Binding#irb๋ฅผ ํ†ตํ•ด ํ‘œ์‹œ๋œ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ผ์ธ์˜ ์ƒ‰์ƒ ๊ฐ•์กฐ ํ‘œ์‹œ์™€ ๊ธฐ๋ณธ ํด๋ž˜์Šค ๊ฐœ์ฒด ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    Ruby ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด 2.7.0 ๋ฆด๋ฆฌ์Šค

  • ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ ์กฐ๊ฐ ๋ชจ์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” Compaction GC๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์ผ๋ถ€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ Ruby ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž‘์—… ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์กฐ๊ฐํ™”๋กœ ์ธํ•œ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„ ์ฆ๊ฐ€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ํž™์— ๊ฐ์ฒด๋ฅผ ํŒจํ‚นํ•˜๋ ค๋ฉด ์ œ์•ˆ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ํŽ˜์ด์ง€ ์ˆ˜๋ฅผ ์ค„์ด๊ณ  ์ž‘์—…์„ ์œ„ํ•ด ํž™์„ ์ตœ์ ํ™”ํ•˜๋Š” GC.compact ๋ฉ”์„œ๋“œ
    CoW(๊ธฐ๋ก ์ค‘ ๋ณต์‚ฌ).

  • ์‹ค์‹œ ๋ชฉ๋ก์˜ ์œ„์น˜("def foo(a,b,c)")์™€ ํ‚ค์›Œ๋“œ("def foo(key: val)")๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ธ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•  ์ค€๋น„๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ‚ค์›Œ๋“œ์™€ ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์ž๋™ ์ธ์ˆ˜ ๋ณ€ํ™˜์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ Ruby 3.0 ๋ธŒ๋žœ์น˜์—์„œ๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋งˆ์ง€๋ง‰ ์ธ์ˆ˜๋ฅผ ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๊ณ , ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ธ์ˆ˜๋ฅผ ๋งˆ์ง€๋ง‰ ํ•ด์‹œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ณ , ๋งˆ์ง€๋ง‰ ์ธ์ˆ˜๋ฅผ ์œ„์น˜ ๋ฐ ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    def foo(ํ‚ค: 42); ๋; foo({ํ‚ค: 42}) #๊ฒฝ๊ณ 
    def foo(**kw); ๋; foo({key: 42}) # ๊ฒฝ๊ณ 
    def foo(ํ‚ค: 42); ๋; foo(**{key: 42}) # ํ™•์ธ
    def foo(**kw); ๋; foo(**{key: 42}) # ํ™•์ธ

    def foo(h, **kw); ๋; foo(key: 42) # ๊ฒฝ๊ณ 
    def foo(h, ํ‚ค: 42); ๋; foo(ํ‚ค: 42) #๊ฒฝ๊ณ 
    def foo(h, **kw); ๋; foo({key: 42}) # ํ™•์ธ
    def foo(h, ํ‚ค: 42); ๋; foo({key: 42}) # ํ™•์ธ

    def foo(h={}, ํ‚ค: 42); ๋; foo("key" => 43, key: 42) # ๊ฒฝ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.
    def foo(h={}, ํ‚ค: 42); ๋; foo({"key" => 43, key: 42}) # ๊ฒฝ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.
    def foo(h={}, ํ‚ค: 42); ๋; foo({"key" => 43}, key: 42) # ํ™•์ธ

    def foo(opt={}); ๋; foo( ํ‚ค: 42 ) # ํ™•์ธ

    def foo(h, **nil); ๋; foo(ํ‚ค: 1) # ์ธ์ˆ˜ ์˜ค๋ฅ˜
    def foo(h, **nil); ๋; foo(**{key: 1}) # ArgumentError
    def foo(h, **nil); ๋; foo("str" โ€‹โ€‹โ€‹โ€‹=> 1) # ArgumentError
    def foo(h, **nil); ๋; foo({key: 1}) # ํ™•์ธ
    def foo(h, **nil); ๋; foo({"str" โ€‹โ€‹โ€‹โ€‹=> 1}) # ํ™•์ธ

    h = {}; def foo(*a) end; foo(**h) # [] h = {}; def foo(a) ๋; foo(**h) # {} ๋ฐ ๊ฒฝ๊ณ 
    h = {}; def foo(*a) end; foo(h) # [{}] h = {}; def foo(a) ๋; foo(h) # {}

  • ๊ธฐํšŒ ๋ธ”๋ก ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ง„ ๊ธฐ๋ณธ ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    [1, 2, 3].each { puts @1 } # like [1, 2, 3].each { |i| ๋‚ด๊ฐ€ }

  • ์ดˆ๊ธฐ๊ฐ’์ด ์—†๋Š” ๋ฒ”์œ„์— ๋Œ€ํ•œ ์‹คํ—˜์  ์ง€์›์ž…๋‹ˆ๋‹ค.

    ary[..3] # ary[0..3]๊ณผ ๋™์ผ rel.where(ํŒ๋งค: ..100)

  • ๊ฐ ์š”์†Œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ํšŸ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” Enumerable#tally ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

    ["a", "b", "c", "b"].tally
    #=> {โ€œaโ€=>1, โ€œbโ€=>2, โ€œcโ€=>1}

  • "self" ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•œ ๋น„๊ณต๊ฐœ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

    ๋””ํ‘ธ
    end
    ๋น„๊ณต๊ฐœ : foo
    ์ž๊ธฐ.foo

  • ๊ฒŒ์œผ๋ฅธ(Enumerator::Lazy) ์—ด๊ฑฐํ˜•์—์„œ ์ผ๋ฐ˜ ์—ด๊ฑฐํ˜•์„ ์ƒ์„ฑํ•˜๋Š” Enumerator::Lazy#eager ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

    a = %w(foo ๋ฐ” ๋ฐ”์ฆˆ)
    e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.์—ด๋ ฌํ•œ
    p e.class #=> ์—ด๊ฑฐ์ž
    e.map {|x| x + "?" } #=> ["FOO!?", "BAR!?", "BAZ!?"]

  • ์‹คํ—˜์ ์ธ JIT ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๊ฐœ๋ฐœ์ด ๊ณ„์†๋˜์–ด Ruby ์–ธ์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Ruby์—์„œ ์ œ์•ˆ๋œ JIT ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋จผ์ € C ์ฝ”๋“œ๋ฅผ ๋””์Šคํฌ์— ์ž‘์„ฑํ•œ ํ›„ ์™ธ๋ถ€ C ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ธฐ๊ณ„ ๋ช…๋ น์–ด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค(GCC, Clang ๋ฐ Microsoft VC++ ์ง€์›). ์ƒˆ ๋ฒ„์ „์—์„œ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ธ๋ผ์ธ ๋ฐฐํฌ ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๊ณ , ์ปดํŒŒ์ผ ์ค‘ ์ตœ์ ํ™” ๋ชจ๋“œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ ์šฉํ•˜๋ฉฐ, "--jit-min-calls"์˜ ๊ธฐ๋ณธ๊ฐ’์ด 5์—์„œ 10000์œผ๋กœ ์ฆ๊ฐ€ํ•˜๊ณ , "--jit-max-cache"๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. 1000์—์„œ 100์œผ๋กœ.
  • CGI.escapeHTML, Monitor ๋ฐ MonitorMixin์˜ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • Module#name, true.to_s, false.to_s ๋ฐ nil.to_s๋Š” ์ง€์ •๋œ ๊ฐ์ฒด์— ๋Œ€ํ•ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๋ฌธ์ž์—ด์ด ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • RubyVM::InstructionSequence#to_binary ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ๊ฐ์†Œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์Œ์„ ํฌํ•จํ•œ ๋‚ด์žฅ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์—…๋ฐ์ดํŠธ๋œ ๋ฒ„์ „
    ๋ฒˆ๋“ค๋Ÿฌ 2.1.2, RubyGems 3.1.2,
    Racc 1.4.15,
    CSV 3.1.2, REXML 3.2.3,
    RSS 0.2.8,
    ๋ฌธ์ž์—ด ์Šค์บ๋„ˆ 1.0.3;

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ธฐ๋ณธ ๋ฐฐํฌ์—์„œ ์™ธ๋ถ€ gem ํŒจํ‚ค์ง€๋กœ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    CMath(cmath ๋ณด์„),
    Scanf (์Šค์บ”ํ”„ ๋ณด์„),
    ์‰˜(์‰˜ ๋ณด์„)
    ๋™๊ธฐํ™” ์žฅ์น˜(๋™๊ธฐํ™” ๋ณด์„),
    ThreadsWait(์Šค์›จ์ดํŠธ ๋ณด์„),
    E2MM(e2mmap ์ ฌ).

  • ๊ธฐ๋ณธ stdlib ๋ชจ๋“ˆ์€ rubygems.org์— ๊ฒŒ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค:
    ๊ธฐ์ค€,
    CG,
    ๋Œ€๋ฆฌ์ž,
    getoptlong,
    ๋„ทํŒ,
    net-smtp
    ์˜คํ”ˆ3,
    p์Šคํ† ์–ด,
    ํ•˜๋‚˜์”ฉ ์ผ์–ด๋‚˜๋Š” ๊ฒƒ. ๋ชจ๋‹ˆํ„ฐ ๋ชจ๋“ˆ์ด rubygems.org๋กœ ์ด๋™๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
    ๊ด€์ฐฐ์ž,
    ์‹œ๊ฐ„ ์ดˆ๊ณผ,
    ์ถ”์ ๊ธฐ,
    ๋ฏธ์›€,
    Ruby-core๋กœ๋งŒ ์ œ๊ณต๋˜๋Š” yaml์ž…๋‹ˆ๋‹ค.

  • ์ด์ œ Ruby๋ฅผ ๋นŒ๋“œํ•˜๋ ค๋ฉด C99 ํ‘œ์ค€์„ ์ง€์›ํ•˜๋Š” C ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : opennet.ru

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€