6. April, 2004
6. April, 2004
in by Michael Neumann
start summary::

Rite will be a complete rewRite of the Ruby interpreter, whereas Ruby2 will be the new revision of the Ruby language.

Rite:

  • bytecode
  • generational GC
  • native threads
  • new regular expression engine (Onigurama)
  • m17n (multilinguization)

Ruby2:

  • real keyword arguments (not just hashes)
  • new block variable scope
  • pre/post/wrap methods
  • selector namespaces (?)
  • a few other modifications that clean up the language (but no dramatic changes, Ruby will stay the same)

This is mainly a repetition of Matz’s ideas presented at RubyConf 2003 "How Ruby Sucks" (did Guido van Rossum ever told you How Python Sucks? :-). More information on this subject is given in Rite or RiteSuggestions.

end summary::

New Local Variable Scope

Block parameters are block-local, whereas all other variable assignments inside the block do no longer create block-local variables.

But what about block-local variables other than the parameters?

Solution 1

By using more block-parameters than actually used for the arguments. For example:

ary.each do |i, aLocal, anotherLocal|
  ...
end

This seems odd to me, as it’s no longer clear how each behaves, which variables are actually parameters, and which are not.

Solution 2

Introduce new syntax for block-local variables. For example:

ary.each do |i| <aLocal, anotherLocal>
  ...
end

Or more verbose:

ary.each do |i|
  local aLocal, anotherLocal
  ...
end

A local * or <*> would then mean, that all used variables are local to the block.

Keyword arguments

Old hash syntax for method calls

Will the following become obsolete?

def foo(hash)
  ...
end

foo("port" => 8080, "url" => "...")

Instead (Rite):

def foo(**hash)
  ...
end

Or explicitly (Rite):

def foo(port: nil, url: nil)
  ...
end

foo(port: 8080, url: "...")

I would argue for making it obsolete, i.e. removing it, for the sake of clearness.

No parentheses?

Will it still be possible to ommit parentheses? Will the following work?

foo port: 8080, url: "..."

I don’t like this when used in combination with keyword arguments, as it reminds me of Smalltalk, but is completely different (first part is a method instead of a receiver/object in ST).

Passing Arguments Through

Will this work?

def wrap_a(*args, **keys, &block)
  a(*args, **keys, &block)
end

Of course, it should!

Complex argument lists

Will this be possible?

def foo(a, x=5, *args, b: 42, c: nil, **keys, &block)
  ...
end

foo(1)
# => a=1, x=5, args=[], b=42, c=nil, keys={}, block=nil

foo(1, 2, 3, 4, c: 5, port: 8080) {...}
# => a=1, x=2, args=[3,4], b=42, c=5, keys={port: 8080}, block={...}

I really don’t want to write a parser for this ;-)

Don’t care argument list

As argument lists become more complicated, wouldn’t it be nice to have a syntax for don’t care? This is especially useful for pre and post methods:

def foo(a, *args, b: 42, c: nil, **keys, &block)
  ...
end

def foo:pre(...)
  # don't care about the arguments
end

Don’t need to write:

def foo:pre(*a, **b, &p)
  ...
end

Maybe isn’t appropriate, as it reminds me of ellipses in C++. Probably no big win in clearness, as usually pre and post methods are used for meta-programming and not by the programmer itself.

Another possible solution is to not perform arity checks for pre or post methods, so that argument lists can be ommited, when not needed:

def foo(a, b, c)
  ...
end

def foo:pre
  puts "pre"
end

But that would make them a bit more special than normal methods are, which is IMHO not a good choice.

Pre/Post/Wrap Methods

Great improvement for meta-programming like Aspect Oriented Programming (AOP).