Ruby HEAD's been evolving in the last 4 months (2006-10)
It's been a while since the last update to my summary of changes in Ruby 1.9 and there are lots of new methods, a few syntactic changes and fundamental changes in the relation between Symbols and Strings.
Some highlights follow, but refer to the expanded changelog for the details (several RSS feeds with abridged ("differential") summaries are available).
I submitted a few patches correcting some issues I discovered while writing this to ruby-core, and they have been applied.
String
Strings are no longer Enumerable, but you can use string.lines to get an enumerator:
"foo\nbar\n".lines.sort # => ["bar\n", "foo\n"]
There's also #bytes
"hello".bytes.to_a # => [104, 101, 108, 108, 111]
Several methods were added: #partition, #rpartition, #start_with?, #end_with?.
"hello, world".partition(/lo/) # => ["hel", "lo", ", world"]
Introspection
Methods returning a list of methods now use symbols instead of strings:
NilClass.instance_methods(false) # => [:to_a, :inspect, :yield, :to_f, :|, :to_s, :&, :to_i, :^, :nil?]
A couple methods were added to test whether an instance variable exists:
"".instance_variable_defined? :@a # => false
There's also Module#class_variable which is IMO misnamed.
class X; @a = 1 end; X.class_variable_defined? :@@a # ~> in Module#class_variable_defined?': `@@a' is not allowed as an instance variable name (NameError)
@a is not a class variable (that'd be @@a) but a class instance variable. This looks like a bug. (ruby-core:9158)
There's also Module#class_variable which will tell you if a class variable (@@cv) is defined:
class X; @@a = 1 end X.class_variable_defined? :@@a # => true
Syntax
Multiple splats were already allowed, and now you can also use mandatory arguments after optional ones:
def m(a, b=nil, *c, d)
[a,b,c,d]
end
m(1,2) # => [1, nil, [], 2]
Symbols vs. Strings
Symbol is now a subclass of String (see also this):
:foo.class.ancestors # => [Symbol, String, Comparable, Object, Kernel, BasicObject]
a = {:foo => 1, "bar" => 2}
a["foo"] # => 1
a[:bar] # => 2
:foo == "foo" # => true
"foo" == :foo # => true
:foo.gsub(/o/, "a") # => :faa
:foo.object_id # => -739527348
:foo.object_id # => -739527348
:foo[1..-1] # => "oo"
:foo.gsub!(/o/, "a") # => ERROR: in `String#gsub!': can't modify frozen string (RuntimeError)
Bugfixes and optimizations
These aren't listed in my changelog, since they don't affect the language formally, but they're important nonetheless:
- small strings and arrays are packed in the associated RString/RArray structure. This is most important for one-char strings.
- several Array operations are now amortized O(1), and several memleaks were fixed
Change summary
See the full summary of changes in Ruby 1.9 for further information.
- .() as a synonym for .call: lambda{|x| x+1}.(1) # => 2
- mandatory arguments after optional arguments allowed (ruby-dev:29014)
- GC improvements
- Module#attr is an alias of attr_reader (RCR#331)
- __send and __send! (before: #invoke_method and #invoke_functional_method) which cannot be removed nor undef()ined
- newlines allowed before ternary colon ruby-dev:29189
- Numeric#step: returns an enumerator object when no block is given
- Integer(nil) raises TypeError ruby-talk::210205
- optimizations: small strings are embedded in the RString structure. You have to use RSTRING_LEN and RSTRING_PTR in your C code. Same for arrays, with RARRAY_LEN and RARRAY_PTR.
- Symbol is a subclass of String
- substrings of symbols are mere strings, not symbols
- sym == str compared as strings (ruby-dev:29554)
- zero-length symbols allowed (ruby-core:08861)
- Time#to_s has a new date format using digits
- Array#to_s is an alias to #inspect. Ditto for Hash.
- Hash#compare_by_identity and Hash#compare_by_identity?
- Struct#inspect does not show a class name for anonymous structs.
- Kernel#instance_variable_defined?
- Kernel#define_singleton_method (ruby-list:42851)
- Module#class_variable_defined?
- Kernel#singleton_methods returns an array of symbols, not strings
- Integer#odd? #even?
- String
- partition, rpartition
- no longer Enumerable (use #each_line)
- #start_with?, #end_width? (ruby-talk:216685)
- #lines, which returns an Enumerator
- #bytes
- to_splat instead of to_ary used to create the array when splatting
- block parameters are always local
__send business - trans (2006-10-12 (Thr) 10:30:59)
Lots of good things coming down the pike. Have to give my opinion on "__send and __send!" though: ugly! I don't understand why '__' prefix would be chosen over current precendence of 'instance_' prefix and/or 'object_' prefix.
mfp 2006-10-12 (Thr) 12:01:57
They used to be #invoke_method and #invoke_functional_method (ugh) and got renamed after a long discussion in ruby-talk.
So now we have
| no private methods | any method |
|---|---|
| __send__ | __send! |
| __send | funcall |
| send |
I don't see why we have __send__, __send and __send! instead of, say, just __send__ and __send__!, though.
Jan Wikholm 2006-10-12 (Thr) 13:52:48
Thank you for this update. Plenty of information to absorb.
an 2006-10-15 (Sun) 07:05:24
__send! is really ugly ;-)
Keyword(s):[blog] [ruby] [frontpage] [1.9] [changelog] [update]
References: