A list of deprecated stuff in Ruby
As APIs evolve it’s inevitable that portions of them will be deprecated. Generally it’s fairly easy to find out what’s deprecated, but for several reasons that’s not the case in Ruby:
- Deprecation is done through the use of C functions such as
rb_warn
&rb_warning
(as opposed to some more transparent methods as Java’s@deprecated
annotation). To see the deprecation messages from those functions you’ll have to run Ruby with-w
. Consider this example code:
string.lines do |line|
puts line
end
ruby -w test.rb
../test.rb:1: warning: passing a block to String#lines is deprecated
-
Alternative Ruby implementations (like
JRuby
andRubinius
) generally don’t produce the same deprecation warnings. For instance -JRuby
doesn’t produce any warnings for the code listed above. One can say that currently deprecations are an MRI implementation detail (although they shouldn’t be). -
Deprecations are rarely mentioned in the API docs.
-
There’s no easy way to find out in which version of Ruby something got deprecated as
rb_warn
is a generic instrumentation for producing all sorts of warnings, as opposed to something created specifically to handle deprecations. -
Some APIs are deprecated only informally (like
Hash#has_key?
andHash#has_value?
). -
Some APIs are deprecated with
Kernel#warn
(likeDigest::Digest
).
All of the above makes it fairly hard to compile a precise list of deprecations, but we’ll go only for a rough cut here. Let see what we can do…
Grepping in Ruby 2.1’s code base reveals the following:
dir.c
2174: rb_warning("Dir.exists? is a deprecated name, use Dir.exist? instead");
enumerator.c
355: rb_warn("Enumerator.new without a block is deprecated; use Object#to_enum");
ext/dbm/dbm.c
338: rb_warn("DBM#index is deprecated; use DBM#key");
ext/gdbm/gdbm.c
453: rb_warn("GDBM#index is deprecated; use GDBM#key");
ext/openssl/ossl_cipher.c
217: rb_warn("arguments for %s#encrypt and %s#decrypt were deprecated; "
ext/sdbm/init.c
331: rb_warn("SDBM#index is deprecated; use SDBM#key");
ext/stringio/stringio.c
656: rb_warn("StringIO#bytes is deprecated; use #each_byte instead");
876: rb_warn("StringIO#chars is deprecated; use #each_char instead");
920: rb_warn("StringIO#codepoints is deprecated; use #each_codepoint instead");
1124: rb_warn("StringIO#lines is deprecated; use #each_line instead");
ext/zlib/zlib.c
3892: rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
4174: rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
file.c
1413: rb_warning("%sexists? is a deprecated name, use %sexist? instead", s, s);
hash.c
529: rb_warn("ignoring wrong elements is deprecated, remove them explicitly");
934: rb_warn("Hash#index is deprecated; use Hash#key");
3470: rb_warn("ENV.index is deprecated; use ENV.key");
io.c
3385: rb_warn("IO#lines is deprecated; use #each_line instead");
3436: rb_warn("IO#bytes is deprecated; use #each_byte instead");
3590: rb_warn("IO#chars is deprecated; use #each_char instead");
3697: rb_warn("IO#codepoints is deprecated; use #each_codepoint instead");
11196: rb_warn("ARGF#lines is deprecated; use #each_line instead");
11243: rb_warn("ARGF#bytes is deprecated; use #each_byte instead");
11282: rb_warn("ARGF#chars is deprecated; use #each_char instead");
11321: rb_warn("ARGF#codepoints is deprecated; use #each_codepoint instead");
object.c
991: rb_warning("untrusted? is deprecated and its behavior is same as tainted?");
1005: rb_warning("untrust is deprecated and its behavior is same as taint");
1020: rb_warning("trust is deprecated and its behavior is same as untaint");
proc.c
663: rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead");
string.c
6407: rb_warning("passing a block to String#lines is deprecated");
6576: rb_warning("passing a block to String#bytes is deprecated");
6665: rb_warning("passing a block to String#chars is deprecated");
6769: rb_warning("passing a block to String#codepoints is deprecated");
vm_method.c
54: rb_warning("rb_clear_cache() is deprecated.");
Below is a cleaned up list of the output shown above. I’ve removed everything that’s unlikely to be of general interest.
Dir.exists?
is a deprecated name, useDir.exist?
insteadEnumerator.new
without a block is deprecated; useObject#to_enum
StringIO#bytes
is deprecated; useStringIO#each_byte
insteadStringIO#chars
is deprecated; useStringIO#each_char
insteadStringIO#codepoints
is deprecated; useStringIO#each_codepoint
insteadStringIO#lines
is deprecated; useStringIO#each_line
insteadFile.exists?
is a deprecated name, useFile.exist?
insteadHash#index
is deprecated; useHash#key
ENV.index
is deprecated; useENV.key
IO#lines
is deprecated; useIO#each_line
insteadIO#bytes
is deprecated; useIO#each_byte
insteadIO#chars
is deprecated; useIO#each_char
insteadIO#codepoints
is deprecated; useIO#each_codepoint
insteadARGF#lines
is deprecated; useARGF#each_line
insteadARGF#bytes
is deprecated; useARGF#each_byte
insteadARGF#chars
is deprecated; useARGF#each_char
insteadARGF#codepoints
is deprecated; useARGF#each_codepoint
insteadObject#untrusted?
is deprecated and its behavior is same asObject#tainted?
Object#untrust
is deprecated and its behavior is same asObject#taint
Object#trust
is deprecated and its behavior is same asObject#untaint
- passing a block to
String#lines
is deprecated - passing a block to
String#bytes
is deprecated - passing a block to
String#chars
is deprecated - passing a block to
String#codepoints
is deprecated
Unfortunately there’s no way to know in which version of Ruby something got deprecated. Obviously most of the things on the list were deprecated before Ruby 2.1. Ideally in the future we’ll get a better deprecation mechanism that actually keeps track of such data.
Hopefully some of you will find this information useful!
We’re planning to get some deprecation tracking in RuboCop, but due to Ruby’s dynamic nature implementing such a feature reliably in a static code analyzer is an impossible task.