ืฉื—ืจื•ืจ ืฉืคืช ื”ืชื›ื ื•ืช Ruby 2.7.0

ืœืื—ืจ ืฉื ื” ืฉืœ ืคื™ืชื•ื— ืคื•ืจืกื ืฉื—ืจื•ืจ ืจื•ื‘ื™ 2.7.0, ืฉืคืช ืชื›ื ื•ืช ื“ื™ื ืžื™ืช, ืžื•ื ื—ื” ืขืฆืžื™ื, ื™ืขื™ืœื” ืžืื•ื“ ื‘ืคื™ืชื•ื— ืชื•ื›ื ื™ื•ืช ื•ืžืฉืœื‘ืช ืืช ืžื™ื˜ื‘ ื”ืชื›ื•ื ื•ืช ืฉืœ Perl, Java, Python, Smalltalk, Eiffel, Ada ื•-Lisp. ืงื•ื“ ื”ืคืจื•ื™ืงื˜ ืžื•ืคืฅ ืชื—ืช ืจื™ืฉื™ื•ื ื•ืช BSD ("2-ืกืขื™ืฃ BSDL") ื•-"Ruby", ื”ืžืชื™ื™ื—ืก ืœื’ืจืกื” ื”ืขื“ื›ื ื™ืช ื‘ื™ื•ืชืจ ืฉืœ ืจื™ืฉื™ื•ืŸ GPL ื•ืชื•ืื ื‘ืื•ืคืŸ ืžืœื ืœ-GPLv3. Ruby 2.7 ื”ื•ื ื”ืžื”ื“ื•ืจื” ื”ืฉื‘ื™ืขื™ืช ื”ืขื™ืงืจื™ืช ืœืื—ืจ ืชื”ืœื™ืš ืคื™ืชื•ื— ืžืชื•ื›ื ืŸ ืฉืœื•ืงื— ืฉื ื” ืœื”ื›ื™ืŸ ืฉื™ืคื•ืจื™ื ืคื•ื ืงืฆื™ื•ื ืœื™ื™ื ื•ืžื™ื™ืฆืจ ืžื”ื“ื•ืจื•ืช ืชื—ื–ื•ืงื” ื›ืœ 2-3 ื—ื•ื“ืฉื™ื.

ื”ืขื™ืงืจื™ ืฉื™ืคื•ืจื™ื:

  • ื ึดืกื™ื•ึนื ึดื™ ืœืชืžื•ืš ื”ืชืืžืช ืชื‘ื ื™ืช (ื”ืชืืžืช ืชื‘ื ื™ืช), ื”ืžืืคืฉืจื™ื ืœืš ืœื—ื–ื•ืจ ืขืœ ืื•ื‘ื™ื™ืงื˜ ื ืชื•ืŸ ื•ืœื”ืงืฆื•ืช ืขืจืš ืื ื™ืฉ ื”ืชืืžื” ืœืชื‘ื ื™ืช.

    ืžืงืจื” [0, [1, 2, 3]] ื‘-[a, [b, *c]] pa #=> 0
    pb #=> 1
    pc #=> [2, 3] ืกื•ืฃ

    ืžืงืจื” {a: 0, b: 1}
    ื‘-{a: 0, x: 1}
    :ืื™ื ื• ื–ืžื™ืŸ
    ื‘-{a: 0, b: var}
    p var #=> 1
    ืกื•ืฃ

  • ืžืขื˜ืคืช ื”ื—ื™ืฉื•ื‘ื™ื ื”ืื™ื ื˜ืจืืงื˜ื™ื‘ื™ื™ื irb (REPL, Read-Eval-Print-Loop) ื›ื•ืœืœืช ื›ืขืช ืขืจื™ื›ื” ืžืจื•ื‘ืช ืฉื•ืจื•ืช, ื”ืžื™ื•ืฉืžืช ื‘ืืžืฆืขื•ืช ืกืคืจื™ื™ื” ืชื•ืืžืช ืงื•-ืงืจื™ืื” ืœื”ืชื‘ืกืก, ื›ืชื•ื‘ ื‘ืจื•ื‘ื™. ืชืžื™ื›ืช 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. ื‘ืื•ืคืŸ ืกืคืฆื™ืคื™, ื”ื•ื ื”ื•ืฆื™ื ืžืฉื™ืžื•ืฉ ืืช ื”ืืจื’ื•ืžื ื˜ ื”ืื—ืจื•ืŸ ื›ืคืจืžื˜ืจื™ื ืฉืœ ืžื™ืœืช ืžืคืชื—, ื”ืขื‘ืจืช ืืจื’ื•ืžื ื˜ื™ื ืžื‘ื•ืกืกื™ ืžื™ืœืช ืžืคืชื— ื›ืคืจืžื˜ืจ ื”-hash ื”ืื—ืจื•ืŸ, ื•ืคื™ืฆื•ืœ ื”ืืจื’ื•ืžื ื˜ ื”ืื—ืจื•ืŸ ืœืคืจืžื˜ืจื™ื ืžื™ืงื•ืžื™ื™ื ื•ืžื™ืœื•ืช ืžืคืชื—.

    def foo (ืžืคืชื—: 42); ืกื•ึนืฃ; foo({key: 42}) # ื”ื–ื”ื™ืจ
    def foo(**kw); ืกื•ึนืฃ; foo({key: 42}) # ื”ื–ื”ื™ืจ
    def foo (ืžืคืชื—: 42); ืกื•ึนืฃ; foo(**{key: 42}) # ื‘ืกื“ืจ
    def foo(**kw); ืกื•ึนืฃ; foo(**{key: 42}) # ื‘ืกื“ืจ

    def foo(h, **kw); ืกื•ึนืฃ; foo(ืžืคืชื—: 42) # ื”ื–ื”ื™ืจ
    def foo(h, ืžืคืชื—: 42); ืกื•ึนืฃ; foo(ืžืคืชื—: 42) # ื”ื–ื”ื™ืจ
    def foo(h, **kw); ืกื•ึนืฃ; foo({ืžืคืชื—: 42}) # ื‘ืกื“ืจ
    def foo(h, ืžืคืชื—: 42); ืกื•ึนืฃ; foo({ืžืคืชื—: 42}) # ื‘ืกื“ืจ

    def foo(h={}, ืžืคืชื—: 42); ืกื•ึนืฃ; foo("key" => 43, ืžืคืชื—: 42) # ืื–ื”ืจื”
    def foo(h={}, ืžืคืชื—: 42); ืกื•ึนืฃ; foo({"key" => 43, key: 42}) # ืื–ื”ืจื”
    def foo(h={}, ืžืคืชื—: 42); ืกื•ึนืฃ; foo({"key" => 43}, ืžืคืชื—: 42) # ื‘ืกื“ืจ

    def foo(opt={}); ืกื•ึนืฃ; foo (ืžืคืชื—: 42 ) # ื‘ืกื“ืจ

    def foo(h, **nil); ืกื•ึนืฃ; foo(ืžืคืชื—: 1) #ArgumentError
    def foo(h, **nil); ืกื•ึนืฃ; foo(**{key: 1}) # ArgumentError
    def foo(h, **nil); ืกื•ึนืฃ; foo("str"=> 1) # ArgumentError
    def foo(h, **nil); ืกื•ึนืฃ; foo({ืžืคืชื—: 1}) # ื‘ืกื“ืจ
    def foo(h, **nil); ืกื•ึนืฃ; foo({"str"=> 1}) # ื‘ืกื“ืจ

    h = {}; def foo(*a) a end; foo(**h) # [] h = {}; def foo(a) a end; foo(**h) # {} ื•ืื–ื”ืจื”
    h = {}; def foo(*a) a end; foo(h) # [{}] h = {}; def foo(a) a end; foo(h) # {}

  • ื”ื–ื“ืžื ื•ืช ืฉื™ืžื•ืฉ ื‘ืฉืžื•ืช ืžืฉืชื ื™ื ืžืžื•ืกืคืจื™ื ื›ื‘ืจื™ืจืช ืžื—ื“ืœ ืขื‘ื•ืจ ืคืจืžื˜ืจื™ ื‘ืœื•ืง.

    [1, 2, 3].each { ืžื›ื ื™ืก @1 } # ื–ื”ื” ืœ-[1, 2, 3].each { |i| ืฉื ืื ื™}

  • ืชืžื™ื›ื” ื ื™ืกื™ื•ื ื™ืช ืœื˜ื•ื•ื—ื™ื ืœืœื ืขืจืš ื”ืชื—ืœืชื™.

    ary[..3] # ื“ื•ืžื” ืœ-ary[0..3] rel.where(ืžื›ื™ืจื•ืช: ..100)

  • ื ื•ืกืคื” ืฉื™ื˜ืช Enumerable#tally, ื”ืกื•ืคืจืช ืืช ืžืกืคืจ ื”ืคืขืžื™ื ืฉื›ืœ ืืœืžื ื˜ ืžืชืจื—ืฉ.

    ["ื", "ื‘", "ื’", "ื‘"]
    #=> {โ€œaโ€=>1, โ€œbโ€=>2, โ€œcโ€=>1}

  • ืžื•ืชืจ ืœืงืจื•ื ืœืฉื™ื˜ื” ืคืจื˜ื™ืช ืขื ื”"ืขืฆืžื™" ื”ืžื™ืœื•ืœื™

    def foo
    ืกื•ืฃ
    ืคืจื˜ื™ :foo
    self.foo

  • ื ื•ืกืคื” ืฉื™ื˜ื” ืžื•ื ื”::ืขืฆืœ#ืœื”ื•ื˜ ืœื™ืฆื•ืจ ืกืคื™ืจื” ืงื‘ื•ืขื” ืžืžื•ื ื” ืขืฆืœืŸ (Enumerator::ืขืฆืœืŸ).

    a = %w(foo bar baz)
    e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.ืœึธื”ื•ึผื˜
    p e.class #=> ืžื•ื ื”
    p e.map {|x| x + "?" } #=> ["FOO!?", "BAR!?", "BAZ!?"]

  • ื”ืคื™ืชื•ื— ืฉืœ ืžื”ื“ืจ JIT ื ื™ืกื™ื•ื ื™ ื ืžืฉืš, ืฉื™ื›ื•ืœ ืœืฉืคืจ ืžืฉืžืขื•ืชื™ืช ืืช ื”ื‘ื™ืฆื•ืขื™ื ืฉืœ ื™ื™ืฉื•ืžื™ื ื‘ืฉืคืช Ruby. ืžื”ื“ืจ JIT ืฉืœ ืจื•ื‘ื™ ื›ื•ืชื‘ ืชื—ื™ืœื” ืงื•ื“ C ืœื“ื™ืกืง, ื•ืœืื—ืจ ืžื›ืŸ ืงื•ืจื ืœืžื”ื“ืจ C ื—ื™ืฆื•ื ื™ ื›ื“ื™ ืœื™ืฆื•ืจ ื”ื•ืจืื•ืช ืžื›ื•ื ื” (ืชื•ืžืš ื‘ืงืจื™ืื” ืœ-GCC, Clang ื•-Microsoft VC++). ื”ื’ืจืกื” ื”ื—ื“ืฉื” ืžื™ื™ืฉืžืช ืฉื™ื˜ื” ืœืคืจื™ืกื” ืžื•ื˜ื‘ืขืช ื‘ืžื™ื“ืช ื”ืฆื•ืจืš, ืžื•ื‘ื˜ื—ืช ื™ื™ืฉื•ื ืกืœืงื˜ื™ื‘ื™ ืฉืœ ืžืฆื‘ื™ ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ื‘ืžื”ืœืš ื”ื”ื™ื“ื•ืจ, ืขืจืš ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ืฉืœ "--jit-min-calls" ื’ื“ืœ ืž-5 ืœ-10000, ื•---jit-max- ืžื˜ืžื•ืŸ" ืž-1000 ืขื“ 100 .
  • ื‘ื™ืฆื•ืขื™ื ืžืฉื•ืคืจื™ื ืฉืœ CGI.escapeHTML, Monitor ื•- MonitorMixin.
  • Module#name, true.to_s, false.to_s ื•-nil.to_s ืžื‘ื˜ื™ื—ื™ื ืฉืžื•ื—ื–ืจืช ืžื—ืจื•ื–ืช ืœืœื ืฉื™ื ื•ื™ ืขื‘ื•ืจ ื”ืื•ื‘ื™ื™ืงื˜ ืฉืฆื•ื™ืŸ.
  • ื”ื’ื•ื“ืœ ืฉืœ ืงื‘ืฆื™ื ื‘ื™ื ืืจื™ื™ื ืฉื ื•ืฆืจื• ืขืœ ื™ื“ื™ ืฉื™ื˜ืช RubyVM::InstructionSequence#to_binary; ื”ื•ืคื—ืช.
  • ื’ืจืกืื•ืช ืžืขื•ื“ื›ื ื•ืช ืฉืœ ืจื›ื™ื‘ื™ื ืžื•ื‘ื ื™ื, ื›ื•ืœืœ
    Bundler 2.1.2, RubyGems 3.1.2,
    Racc 1.4.15,
    CSV 3.1.2, REXML 3.2.3,
    RSS 0.2.8,
    StringScanner 1.0.3;

  • ืกืคืจื™ื•ืช ื”ื•ืขื‘ืจื• ืžื—ื‘ื™ืœืช ื”ื‘ืกื™ืก ืœื—ื‘ื™ืœื•ืช ืื‘ื ื™ ื—ืŸ ื—ื™ืฆื•ื ื™ื•ืช
    CMath (ืคื ื™ื ื” ืฉืœ cmath),
    Scanf (Scanf gem),
    ืžืขื˜ืคืช (ืคื ื™ื ื” ืฉืœ ืžืขื˜ืคืช)
    ืกื ื›ืจื•ืŸ (ืคื ื™ื ื” ืกื ื›ืจื•ืŸ),
    ThreadsWait (ื—ืŸ ื—ืŸ),
    E2MM (ืคื ื™ื ื” e2mmap).

  • ืžื•ื“ื•ืœื™ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ืฉืœ stdlib ืžืชืคืจืกืžื™ื ื‘ืืชืจ rubygems.org:
    ืืžืช ืžื™ื“ื”,
    cgi,
    ื ึธืฆึดื™ื’,
    getoptlong,
    ืจืฉืช ืคื•ืค,
    net-smtp
    ืคืชื•ื— 3,
    pstore,
    ืงึฐืœึธืฃ ื‘ึผื•ึนื“ึตื“. ืžื•ื“ื•ืœื™ ืžื•ื ื™ื˜ื•ืจ ืœื ื”ื•ืขื‘ืจื• ืืœ rubygems.org
    ืžึทืฉืืงึดื™ืฃ
    ืคืกืง ื–ืžืŸ
    ื ื•ืชื‘,
    ืฉื‚ึดื ืึธื”,
    yaml, ืฉืžืกื•ืคืงื™ื ืจืง ื‘-ruby-core.

  • ื‘ื ื™ื™ืช Ruby ื“ื•ืจืฉืช ื›ืขืช ืžื”ื“ืจ C ื”ืชื•ืžืš ื‘ืชืงืŸ C99.

ืžืงื•ืจ: OpenNet.ru

ื”ื•ืกืคืช ืชื’ื•ื‘ื”