ãã®è¨äºã¯ Ruby 2.5.0 preview1 æç¹ã®ãã®ã§ããRuby 2.5 ãªãªã¼ã¹çã«ã¤ãã¦ã¯ http://tmtms.hatenablog.com/entry/2017/12/30/ruby25 ãè¦ã¦ãã ããã
Rubyã¯æ¯å¹´ã¯ãªã¹ãã¹ã«ãã¼ã¸ã§ã³ã¢ããããã¾ãã
ä»å¹´ãåé¡ãªããã°12/25ã«Ruby 2.5ãåºãã¨æãã¾ãã
https://docs.ruby-lang.org/en/trunk/NEWS.html ãå ã«å¤æ´å 容ã調ã¹ã¦ã¿ã¾ããã
- è¨èªä»æ§
- çµã¿è¾¼ã¿ã©ã¤ãã©ãª
- Array#append, #prepend 追å
- Dir.children, Dir.each_child 追å
- Dir.glob :base ãªãã·ã§ã³è¿½å
- Hash#transform_keys, transform_keys! 追å
- IO.pread, IO.pwrite 追å
- Integer.sqrt 追å
- Integer#round, floor, ceil, truncate ãæ´æ°ãè¿ã
- Numeric: coerceå ã®ä¾å¤
- Range: <=>å ã®ä¾å¤
- Object#yield_self 追å
- Process.times ã®ç²¾åº¦åä¸
- String#delete_prefix, delete_suffix, delete_prefix!, delete_suffix! 追å
- String#casecmp, casecmp? ãä¾å¤ãçºçããªã
- String#grapheme_clusters, each_grapheme_cluster 追å
- Thread.name=
- Thread#fetch 追å
- KeyError#receiver, key 追å
- Time.at ã§ç§ä»¥ä¸ã®åä½ãæå®
- Random.raw_seed ã Random.urandom ã«ååå¤æ´
- æ¨æºæ·»ä»ã©ã¤ãã©ãª
- Bundler Gem æ¨æºæ·»ä»
- ERB#result_with_hash 追å
- ERB: trim æå®æ CR LF ã trim
- Net::HTTP ã¹ãã¼ã¿ã¹è¿½å
- Net::HTTP::STATUS_CODES 追å
- Net::HTTP.new ã« no_proxy å¼æ°è¿½å
- Net::HTTP: http_proxyç°å¢å¤æ°ã使ç¨
- Net::HTTP: http_proxyç°å¢å¤æ°ã®èªè¨¼æ å ±ã使ç¨
- RbConfig::SIZE_OF, RbConfig::LIMITS 追å
- Ripper#state, Ripper::EXPR_BEG 追å
- Set#to_s, #=== 追å
- BasicSocket#read_nonblock, #write_nonblock ã O_NONBLOCK ãã»ããããªã
- Socket::Ifaddr#vhid 追å
- WEBrick: Server Name Indication (SNI) ãµãã¼ã
- æ¨æºã©ã¤ãã©ãªãã mathn åé¤
- æ¨æºã©ã¤ãã©ãªãã ubygems åé¤
- ãã®ä»
è¨èªä»æ§
ãããã¬ãã«å®æ°åç §
class Foo end class Bar end # Ruby 2.4 Foo::Bar #=> Bar # Ruby 2.5 Foo::Bar #=> NameError ä¾å¤
2.5 ã®æ¹ãèªç¶ã§ããã
rescue/else/ensure ç¯
def foo begin ... rescue ... end end
ããã¯å¾æ¥ãã次ã®ããã« begin ãçç¥ã§ãã¾ãããã
def foo ... rescue ... end
2.5ããã¯doãendãããã¯ã§ãçç¥ã§ãã¾ãã
array.each do begin ... rescue ... end end
â
array.each do ... rescue ... end
ç°¡æ½ã«æ¸ãã¦è¯ãã§ãã
æååå å¼ã®Refinement
class A def to_s "a" end end module B refine A do def to_s "b" end end end class C using B def x A.new.to_s #=> "b" "#{A.new}" #=> "b" 2.4 ã§ã¯ "a" end end
Unicode ãã¼ã¸ã§ã³ 10.0.0
Ruby 2.4 㯠9.0.0
Unicode 9.0.0 㨠10.0.0 ã®éãã¯ããã£ã¦ã¾ãããâ¦ã
çµã¿è¾¼ã¿ã©ã¤ãã©ãª
Array#append, #prepend 追å
append, prepend 㯠push, unshift ã¨åããªãã§ãããåããã¨ãããã«ãè¤æ°ã®ååãããã£ã¦ã®ãRubyã£ã½ãã§ããã
a = [1, 2, 3] a.append 4 a #=> [1, 2, 3, 4] a.prepend 0 a #=> [0, 1, 2, 3, 4]
Dir.children, Dir.each_child 追å
ãã£ã¬ã¯ããªå
ã®ã¨ã³ããªã .
, ..
ãé¤ãã¦è¿ãã¡ã½ããã追å ããã¾ããã
Dir.entries("/tmp/x") #=> ["..", "abc", "."] Dir.children("/tmp/x") #=> ["abc"]
Dir.foreach("/tmp/x"){...} # ã.ãã..ããå«ã Dir.each_child("/tmp/x"){...} # ã.ãã..ããå«ã¾ãªã
Dir.glob :base ãªãã·ã§ã³è¿½å
Dir.glob ã«ã«ã¬ã³ããã£ã¬ã¯ããªã®ä»£ããã®ãã¹ãæå®ã§ãããªãã·ã§ã³ã追å ããã¾ããã
Dir.glob("/tmp/x/*") #=> ["/tmp/x/abc"] Dir.glob("*", base: "/tmp/x") #=> ["abc"]
Hash#transform_keys, transform_keys! 追å
ããã·ã¥ä¸ã®å¤ãå¤æãã transform_values ã¡ã½ãã㯠2.4 ããããã¾ãããããã¼ãå¤æ´ãã transform_keys ã¡ã½ããã追å ããã¾ããã
{a: 1, b: 2, c: 3}.transform_keys(&:upcase) #=> {A: 1, B: 2, C: 3} {a: 1, b: 2, c: 3}.transform_values{|v| v*2} #=> {a: 2, b: 4, c: 6} âãã㯠2.4 ãã
IO.pread, IO.pwrite 追å
ãã¡ã¤ã«ã®ç¹å®ã®ä½ç½®ãã read, write ããã¡ã½ãã追å ãPOSIXã®ååã·ã¹ãã ã³ã¼ã«ã¨åãã ãã¡ã¤ã«ãã¤ã³ã¿ã¯å¤æ´ããã¾ããã
File.open("/tmp/x/abc") do |f| f.read(5) #=> "abcde" f.pread(10, 3) #=> "defghijklm" f.read(5) #=> "fghij" end
Integer.sqrt 追å
å¹³æ¹æ ¹ãæ´æ°ã§è¿ãã
Integer.sqrt(9) #=> 3 Integer.sqrt(15) #=> 3 Integer.sqrt(16) #=> 4
Integer#round, floor, ceil, truncate ãæ´æ°ãè¿ã
# Ruby 2.4 123.round(1) #=> 123.0 123.round(-1) #=> 120 # Ruby 2.5 123.round(1) #=> 123 123.round(-1) #=> 120
Numeric: coerceå ã®ä¾å¤
æ°å¤ã¨ãªãã¸ã§ã¯ããæ¯è¼ããæã«ãcoerce ã¡ã½ãããå¼ã°ãã¦ããã§ããããã®éã«çºçããä¾å¤ã ArgumentError ã¨ãªã£ã¦é è½ããã¦ãã¾ã£ã¦ããã®ã§ããããã®ã¾ã¾ä¾å¤ãä¸ããããã«ãªãã¾ããã
class A def coerce(other) raise 'hoge' end end # Ruby 2.4 1 < A.new #=> in `<': comparison of Integer with A failed (ArgumentError) # Ruby 2.5 1 < A.new #=> in `coerce': hoge (RuntimeError)
Range: <=>å ã®ä¾å¤
ãããåä¸ã§ãã
class A def <=>(x) raise 'hoge' end end # Ruby 2.4 Range.new(A.new, A.new) #=> in `initialize': bad value for range (ArgumentError) # Ruby 2.5 Range.new(A.new, A.new) #=> in `<=>': hoge (RuntimeError)
Object#yield_self 追å
# tap ã¯åãããã (1.8 ?) 123.tap{|x| x*2} #=> 123 # 2.5 ãã 123.yield_self{|x| x*2} #=> 246
Process.times ã®ç²¾åº¦åä¸
# Ruby 2.4 % ruby -e 'p Process.times' #<struct Process::Tms utime=0.06, stime=0.01, cutime=0.0, cstime=0.0> # Ruby 2.5 ruby -e 'p Process.times' #<struct Process::Tms utime=0.071065, stime=0.015792, cutime=0.0, cstime=0.0>
String#delete_prefix, delete_suffix, delete_prefix!, delete_suffix! 追å
"abcdefg".delete_prefix("abc") #=> "defg" "abcdefg".delete_suffix("efg") #=> "abcd"
String#casecmp, casecmp? ãä¾å¤ãçºçããªã
# Ruby 2.4 "hoge".casecmp(123) #=> TypeError # Ruby 2.5 "hoge".casecmp(123) #=> nil
String#grapheme_clusters, each_grapheme_cluster 追å
Unicodeã®åææååä½ã§å¦ç
gaga = "ããã" # 1æåç®ã¯ãããã¨ãããã®åææå gaga.chars #=> ["ã", "ã", "ã"] gaga.grapheme_clusters #=> ["ãã", "ã"]
Thread.name=
ã¹ã¬ããã«ååãã¤ãããã¨ãã§ããæ©è½ã Ruby 2.3ãããã£ããã§ãããWindows 10 ã§ãæå¹ã«ãªã£ããããã§ããWindows 使ã£ã¦ãªãã®ã§æªç¢ºèªã§ãã
Thread.new do Thread.current.name = "hogehoge" end
% ps -L -o pid,lwp,comm -p 14655 PID LWP COMMAND 14655 14655 ruby 14655 14656 ruby-timer-thr 14655 14657 hogehoge
Thread#fetch 追å
key ãç¡ãå ´åã« Hash#[key]
㯠nil ãè¿ãã¦ãHash#fetch(key)
ã¯ä¾å¤ãçºçããããã§ãããããã¨åããããªæ¯ãèãããã Thread#fetch
ã追å ããã¾ããã
Thread.current[:hoge] #=> nil Thread.current.fetch(:hoge) #=> KeyError "key not found: hoge" Thread.current.fetch(:hoge, 123) #=> 123
KeyError#receiver, key 追å
ä¾å¤ãçºçãããªãã¸ã§ã¯ãã¨ãã¼ãä¾å¤ã«ä¿æãããããã«ãªãã¾ããã
begin hash = {a: 123} hash.fetch(:b) rescue KeyError => e e.receiver #=> {a: 123} e.key #=> :b end
Time.at ã§ç§ä»¥ä¸ã®åä½ãæå®
Time.at(1511056368, 123456).nsec #=> 123456000 Time.at(1511056368, 123456.789).nsec #=> 123456789 Time.at(1511056368, 123456789, :nsec).nsec #=> 123456789
Random.raw_seed ã Random.urandom ã«ååå¤æ´
æ¨æºæ·»ä»ã©ã¤ãã©ãª
Bundler Gem æ¨æºæ·»ä»
ERB#result_with_hash 追å
ã³ã³ããã¹ãã®å¤æ°ãããªãã¦ãããã·ã¥ã§å¤ã渡ããã¨ãã§ããããã«ãªãã¾ããã
require "erb" name = "tmtms" ERB.new("Hello <%=name%>").result #=> "Hello tmtms"
require "erb" ERB.new("Hello <%=name%>").result_with_hash(name: "tmtms")
ERB: trim æå®æ CR LF ã trim
LFåç¬ã ã¨åé¤ããã¾ããããCR LFã¯åé¤ãããªãã£ãã®ãåé¤ãããããã«ãªãã¾ããã
# Ruby 2.4 require 'erb' ERB.new("<%=123%>\r\n", nil, 1).result #=> "123\r\n" # Ruby 2.5 require 'erb' ERB.new("<%=123%>\r\n", nil, 1).result #=> "123"
Net::HTTP ã¹ãã¼ã¿ã¹è¿½å
'102' => Net::HTTPProcessing, '208' => Net::HTTPAlreadyReported, '421' => Net::HTTPMisdirectedRequest, '451' => Net::HTTPUnavailableForLegalReasons, '506' => Net::HTTPVariantAlsoNegotiates, '508' => Net::HTTPLoopDetected, '510' => Net::HTTPNotExtended,
Net::HTTP::STATUS_CODES 追å
require 'net/http/status' Net::HTTP::STATUS_CODES #=> {100=>"Continue", 101=>"Switching Protocols", # 102=>"Processing", 200=>"OK", 201=>"Created", # 202=>"Accepted", 203=>"Non-Authoritative Information", # 204=>"No Content", 205=>"Reset Content", 206=>"Partial Content", # ...}
Net::HTTP.new ã« no_proxy å¼æ°è¿½å
no_proxy = "example.com,example.net:8080" HTTP.new(address, port, proxy_addr, proxy_port, proxy_user, proxy_pass, no_proxy)
Net::HTTP: http_proxyç°å¢å¤æ°ã使ç¨
HTTPãããã·æ å ±ã¨ãã¦http_proxyç°å¢å¤æ°ã使ãããããã«ãªãã¾ããã
Net::HTTP: http_proxyç°å¢å¤æ°ã®èªè¨¼æ å ±ã使ç¨
http://user:password@proxy:port/
ãã ãWindowsã§ã¯ä½¿ãããªãããã§ããç°å¢å¤æ°ãããã»ã¹ãã¨ã«ç¬ç«ãã¦ãªãããï¼
ãã ã Linux, FreeBSD, Darwin ã«éããã¾ãã
ps ã³ãã³ãçã§ãä»ã®ã¦ã¼ã¶ã¼ã«ç°å¢å¤æ°ã®å¤ãåç
§ãããå¯è½æ§ãããããã®ããã§ãã
RbConfig::SIZE_OF, RbConfig::LIMITS 追å
require "rbconfig/sizeof" RbConfig::SIZEOF #=> {"int"=>4, "short"=>2, "long"=>8, "long long"=>8, # "__int128"=>16, "off_t"=>8, "void*"=>8, "float"=>4, # "double"=>8, "time_t"=>8, "clock_t"=>8, "size_t"=>8, # ... RbConfig::LIMITS #=> {"FIXNUM_MAX"=>4611686018427387903, # "FIXNUM_MIN"=>-4611686018427387904, "CHAR_MAX"=>127, # "CHAR_MIN"=>-128, "SCHAR_MAX"=>127, "SCHAR_MIN"=>-128, # "UCHAR_MAX"=>255, "WCHAR_MAX"=>2147483647, # ...
Ripper#state, Ripper::EXPR_BEG 追å
Set#to_s, #=== 追å
s = Set.new([1, 2, 3]) # Ruby 2.4 s.to_s #=> "#<Set:0x00560b825243b8>" s === 2 #=> false s === s #=> true # Ruby 2.5 s.to_s #=> "#<Set: {1, 2, 3}>" s === 2 #=> true Set#include? ã¨åã s === s #=> false
to_s
ã¯ãããã©ã===
ã¯äºæçãªåé¡ããããããããªãã§ããã
BasicSocket#read_nonblock, #write_nonblock ã O_NONBLOCK ãã»ããããªã
require 'io/nonblock' s = TCPSocket.new("127.0.0.1", 80) s.nonblock? #=> false s.read_nonblock(10) # Ruby 2.4 s.nonblock? #=> true # Ruby 2.5 s.nonblock? #=> false
Socket::Ifaddr#vhid 追å
vhid ãä½ãªã®ãããããªãã£ãã§ããBSDã§ä½¿ããã¦ãä½ãï¼
WEBrick: Server Name Indication (SNI) ãµãã¼ã
SSL/TLSã®ä½ããããã§ããããããã£ã¦ã¾ããã
æ¨æºã©ã¤ãã©ãªãã mathn åé¤
ãããã¾ã使ããã¦ãªãããï¼
æ¨æºã©ã¤ãã©ãªãã ubygems åé¤
ruby ã¯ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ -r
ã§ã©ã¤ãã©ãªãèªã¿è¾¼ãããã§ãããr ã§å§ã¾ãååã®ã©ã¤ãã©ãªã®å ´åã¯å
é ã® r ãçããååã®ã©ã¤ãã©ãªãç¨æãããã¨ã§ããªãã·ã§ã³ã® -r
ã¨åããã¦èªç¶ã«èªããããã«ãªãã¾ãã
ubygems 㯠rubygems ã®å¥åã§ã-rubygems
ã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã§ä½¿ç¨ã§ããããã«ããããã®ãã®ã§ãããrubygems 㯠require ããªãã¦ãæ¨æºã§ä½¿ç¨ãããããããä¸è¦ãªã®ã§ããã
ãã®ä»
ããã¯ãã¬ã¼ã¹ã®é çª
æ¨æºã¨ã©ã¼åºåã端æ«ã®å ´åã«è¡¨ç¤ºãéé ã«ãªãã¾ãã
# Ruby 2.4 % ruby /tmp/a.rb /tmp/a.rb:8:in `c': unhandled exception from /tmp/a.rb:5:in `b' from /tmp/a.rb:2:in `a' from /tmp/a.rb:10:in `<main>'
# Ruby 2.5 % ruby /tmp/a.rb Traceback (most recent call last): 3: from /tmp/a.rb:10:in `<main>' 2: from /tmp/a.rb:2:in `a' 1: from /tmp/a.rb:5:in `b' /tmp/a.rb:8:in `c': unhandled exception
æ¨æºã¨ã©ã¼åºåã端æ«ã§ãªããã°å¾æ¥éãã
% ruby /tmp/a.rb 2>&1 | cat /tmp/a.rb:8:in `c': unhandled exception from /tmp/a.rb:5:in `b' from /tmp/a.rb:2:in `a' from /tmp/a.rb:10:in `<main>'
configure ã§æ¡å¼µã©ã¤ãã©ãªãå¼·å¶
é常㯠configure æã®ç°å¢ã«å¿ãã¦ä½¿ããã©ã¤ãã©ãªãèªåå¤å¥ããã¾ããã--with-ext
ãªãã·ã§ã³ã§å¼·å¶ãããã¨ãã§ãã¾ããã³ã³ãã¤ã«ã§ããç°å¢ã§ãªãå ´å㯠make ã§ã¨ã©ã¼ã«ãªãã¾ãã
% ./configure --with-ext=openssl,+ % make ... *** Following extensions are not compiled: openssl: Could not be configured. It will not be installed. /tmp/ruby-2.5.0-preview1/ext/openssl/extconf.rb:94: OpenSSL library could not be found. You might want to use --with-openssl-dir=<dir> option to specify the prefix where OpenSSL is installed. Check ext/openssl/mkmf.log for more details. *** Fix the problems, then remove these directories and try again if you want. exts.mk:1853: ã¿ã¼ã²ãã 'note' ã®ã¬ã·ãã§å¤±æãã¾ãã make[1]: *** [note] ã¨ã©ã¼ 1 make[1]: ãã£ã¬ã¯ã㪠'/tmp/ruby-2.5.0-preview1' ããåºã¾ã uncommon.mk:236: ã¿ã¼ã²ãã 'build-ext' ã®ã¬ã·ãã§å¤±æãã¾ãã make: *** [build-ext] ã¨ã©ã¼ 2
çµæ§éäºæãå¤ããããªæ°ã¯ãã¾ããããããã便å©ã«ãªã£ã¦ã¾ãããæå¾ ï¼