Ruby-dev summary 23459-23562

Hi all,

This is a summary of ruby-dev ML in these days.
(ruby-dev 23459-23487 + 23488-23562)

[ruby-dev:23465] Re: [ruby-talk:99318] 0.0000000000000000001 == 0.0 should be false

As matz said in [ruby-talk:99375], H.Yamamoto made a patch
on the problem of [ruby-talk:99318] and commited it.

– TAKAHASHI Masayoshi

[ruby-dev:23511] [Oniguruma] Version 3.0.0

K.Kosako released Oniguruma 3.0.0.
New features of this release are:

* UTF-16 BE, LE support
* works with ruby 1.9 only (1.6/1.8 supported is removed)

[ruby-dev:23520] DBM::READER

Tanaka Akira proposed a new flag DBM::READER, to open a DBM in
read-only mode. Matz agreed with him and the patch is incorporated.

[ruby-dev:23533] specifications of parameters and variables in Ruby 2.0

SASADA Koichi posted a summary of the latest specifications of method
parameters, block parameters and block variables that he heard from matz.

[Local Variables]

  • Local variables are method-local.

  • Block parameters are block-local.

  • The name space of local variables and one of block parameters are
    exclusive. e.g.

    i = 1
    iter {|i| # causes error

    }

[Return Values and Parameter Passing]

  • return a, b',yield a, b’ and `*array’ makes a Values object.

    return 1, 2 --> Values(1,2)
    yield 1, 2 --> Values(1,2)
    *[1, 2] --> Values(1,2)

  • Multiple assignment takes care of only Values objects.

    a, b = 1 # a=1, b=nil
    a, = 1 # a=1
    a, * = 1 # a=1
    *a = 1 # a=[1]

    • = 1 # (ignored)
      a = 1 # a=1
      a, b = Values(1,2) # a=1, b=2
      a, = Values(1,2) # a=1
      a, * = Values(1,2) # a=1
      *a = Values(1,2) # a=[1,2]
    • = Values(1,2) # (ignored)
      a = Values(1,2) # a=Values(1,2)

    def yieldSingle
    yield 1
    end

    yieldSingle {|a,b| } # error / a=1, b=nil (not decided yet)
    yieldSingle {|a, | } # a=1
    yieldSingle {|a,*| } # a=1
    yieldSingle {|*a| } # a=[1]
    yieldSingle {|a| } # a=1

    def yieldValues
    yield 1,2
    end

    yieldValues {|a,b| } # a=1, b=2
    yieldValues {|a, | } # error / a=1 (not decided yet)
    yieldValues {|a,*| } # a=1
    yieldValues {|*a| } # a=[1,2]
    yieldValues {|a| } # error

[Block Parameters]

  • Allows Proc#call to take a block.

    def m(&block)
    block.call { p “OK” }
    end
    m {|&b| b.call } #=> “OK”

[Keyword Arguments]

  • Syntax

    def m(a, b=nil, *rest, c:val, **krest)
    p a #=> 1
    p b #=> 2
    p rest #=> [3, 4, 44, 444]
    p c #=> 55
    p krest #=> {:d => 66, :e => 77, :f => 88}
    end

    array = [4, 44, 444]
    hash = {e: 77, f: 88}
    m(1, 2, 3, *array, c:55, d:66, **hash)

  • Lambda blocks MIGHT accept keyword arguments.
    (makes `lambda’ a reserved word?)

– Minero Aoki

ruby-dev summary index:
http://i.loveruby.net/en/ruby-dev-summary.html

Hi –

Minero Aoki aamine@loveruby.net writes:

[ruby-dev:23533] specifications of parameters and variables in Ruby 2.0

SASADA Koichi posted a summary of the latest specifications of method
parameters, block parameters and block variables that he heard from matz.

[Local Variables]

  • Local variables are method-local.

  • Block parameters are block-local.

  • The name space of local variables and one of block parameters are
    exclusive. e.g.

    i = 1
    iter {|i| # causes error

    }

I thought the whole problem was that people wanted to be able to use
the same names in blocks without a clash. The argument was always:
what if you cut-and-paste a block from somewhere, or change a local
variable name accidentally to the same as a block variable name? (My
answer was always: there’s no problem, so let’s leave it the way it is
now, but that isn’t going to happen :slight_smile:

[Return Values and Parameter Passing]

  • return a, b', yield a, b’ and `*array’ makes a Values object.

    return 1, 2 → Values(1,2)
    yield 1, 2 → Values(1,2)

Does that mean:

def m
yield 1,2
end

m {|*a| puts a.class } # “Values”

?

It doesn’t look like it, from the multiple assignment example below (a
looks like an Array). But then I don’t understand exactly what role
is played by the Values object in the yield example.

[…]

def yieldValues
  yield 1,2
end

[…]

yieldValues {|a|   } # error

Does that mean that all method/block/lambda calling syntax is now
unified? Meaning: they all will care equally about number of
arguments?

[…]

def m(a, b=nil, *rest, c:val, **krest)

I have no convincing argument against this (I wish I did :slight_smile: except to
note that we’re getting into really heavy punctuation. I know that’s
not a very scientific observation… but I’m wondering how different
Ruby 2.0 is going to look.

Thanks for the summary!

David

···


David A. Black
dblack@wobblini.net

  • Multiple assignment takes care of only Values objects.

a, b = 1 # a=1, b=nil

a, b = Values(1,2) # a=1, b=2

Does this mean that:

a,b = b,a

won’t work any more? That it’ll have to be:
a,b = Values( b,a )

? If so, then yikes!

  • return a, b', yield a, b’ and `*array’ makes a Values object.

“a Values” sounds a little strange to my ears.

  • Lambda blocks MIGHT accept keyword arguments.
    (makes `lambda’ a reserved word?)

What would this look like in a program?

Paul

···

On Tue, May 25, 2004 at 11:00:03PM +0900, Minero Aoki wrote:

Minero Aoki wrote:

Hi all,

Moin!

  • Allows Proc#call to take a block.

    def m(&block)
    block.call { p “OK” }
    end
    m {|&b| b.call } #=> “OK”

Yay, finally we’ll be able to use define_method() everywhere where we
would use def instead.

However all this raises some questions:

  1. What will yield(*) do?

  2. What will happen with these examples?

    define_method(:foo) { |arg| result = arg }
    foo(5); result # => 5 or ~> NameError?

    Or more interesting:

    define_method(:foo) { foo = nil; return true }
    foo # => true or nil or NameError?
    foo # => true or nil?

  3. What will happen with these examples?

    [1, 2, 3].each do |item|
    [1, 2, 3].each do |item|
    # Exception or reassignment of outer item or
    # own private inner item?
    end
    end

    [1, 2, 3].each do |item|
    [1, 2, 3].each do |inner_item|
    item += 1 if item == inner_item
    end
    p item
    end

Regards,
Florian Gross

Why do we need to make a distinction beetween named arguments and
positional ones?
Given that they will be considered Values can’t we make Value both an
array and an hash?

I’m stupid and I really need to sleep, but why can’t we handle this
just from the calling side?
say:

def m(a,b=nil,c=val,*rest,**krest)
p a # 1
p b # 2
p c # 55
p rest # [3, 4, 44, 444]
p krest # {:d => 66, :e => 77, :f => 88}
end
m(1, 2, c:55, d:66,3,*array, **hash)

This way we could take advantage of all the existing code, and
write stuff like:

def f(a=10,b=20,c=30)
return a,b,c
end

p f() # [10,20,30]
p f(*[1,2,3]) # [1,2,3]
p f(a:10,c:40) # [10,20,40]

···

il Tue, 25 May 2004 23:00:03 +0900, Minero Aoki aamine@loveruby.net ha scritto::

[Keyword Arguments]

  • Syntax

    def m(a, b=nil, *rest, c:val, **krest)
    p a #=> 1
    p b #=> 2
    p rest #=> [3, 4, 44, 444]
    p c #=> 55
    p krest #=> {:d => 66, :e => 77, :f => 88}
    end

    array = [4, 44, 444]
    hash = {e: 77, f: 88}
    m(1, 2, 3, *array, c:55, d:66, **hash)

  • The name space of local variables and one of block parameters are
    exclusive. e.g.

    i = 1
    iter {|i| # causes error

    }

I thought the whole problem was that people wanted to be able to use
the same names in blocks without a clash. The argument was always:

See
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/52462,
regarding shadowing.

what if you cut-and-paste a block from somewhere, or change a local
variable name accidentally to the same as a block variable name? (My
answer was always: there’s no problem, so let’s leave it the way it is
now, but that isn’t going to happen :slight_smile:

A silent error is much worse than a parse-time one.

···

On Tue, May 25, 2004 at 11:55:00PM +0900, David Alan Black wrote:


Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Netscape is not a newsreader, and probably never shall be.
– Tom Christiansen

Minero Aoki wrote:

Hi all,

Moin!

  • Allows Proc#call to take a block.
    def m(&block)
    block.call { p “OK” }
    end
    m {|&b| b.call } #=> “OK”

Yay, finally we’ll be able to use define_method() everywhere where we
would use def instead.

However all this raises some questions:

  1. What will yield(*) do?

I would assume the same as currently: it expands to zero arguments,
becomes yield()

  1. What will happen with these examples?

    define_method(:foo) { |arg| result = arg }
    foo(5); result # => 5 or ~> NameError?

    Or more interesting:

    define_method(:foo) { foo = nil; return true }
    foo # => true or nil or NameError?
    foo # => true or nil?

IIUC, the first snippet would give a NameError, the second would return
true twice. That’s the way it is now…

Why would rescoping rules be changed? Currently, when you call
define_method, Class.new, Module.new, etc., the block is rescoped (is
that the right word?) and local variables never leak in. So, assuming
they don’t make a silly change, define_method would be exactly
orthogonal to def…end:

define_method(:foo){|a,b,*c,&d| a + d[c] + b}
def foo(a,b,*c,&d) a + d[c] + b end

  1. What will happen with these examples?

    [1, 2, 3].each do |item|
    [1, 2, 3].each do |item|
    # Exception or reassignment of outer item or
    # own private inner item?
    end
    end

It looks like an exception, from the explanation. I’m not too excited
about that, but I guess it could help protect you from logic errors.

[1, 2, 3].each do |item|
[1, 2, 3].each do |inner_item|
item += 1 if item == inner_item
end
p item
end

I think this would work like you expect, since only block parameters
are private to inside the block. the item += 1 part should leak out to
the surrounding block.

Disclaimer: This is only based on the way I read it; I could very
likely be all wet. :slight_smile:

cheers,
Mark

···

On May 25, 2004, at 12:13 PM, Florian Gross wrote:

Hi,

···

In message “Re: ruby-dev summary 23459-23562” on 04/05/26, “SER” ser@germane-software.com writes:

Does this mean that:

a,b = b,a

won’t work any more? That it’ll have to be:
a,b = Values( b,a )

No. “b,a” in “a,b = b,a” is a shorthand for “Values(b,a)”.
Note that it is still not the final decision.

						matz.
  1. What will yield(*) do?

Same as “yield”, not value attached.

  1. What will happen with these examples?

    define_method(:foo) { |arg| result = arg }
    foo(5); result # => 5 or ~> NameError?

  1. There will be no in-block variables.

Or more interesting:

define_method(:foo) { foo = nil; return true }
foo # => true or nil or NameError?
foo # => true or nil?

nil. You will need to declare method local variables inside of
methods defined by define_method, for example:

define_method(:foo) {local{|foo=nil| return true}}

  1. What will happen with these examples?

    [1, 2, 3].each do |item|
    [1, 2, 3].each do |item|
    # Exception or reassignment of outer item or
    # own private inner item?
    end
    end

Error (by shadowing variable) or warning.

[1, 2, 3].each do |item|
[1, 2, 3].each do |inner_item|
item += 1 if item == inner_item
end
p item
end

It will print 4,4,4, as it does now.

						matz.
···

In message “Re: ruby-dev summary 23459-23562” on 04/05/26, Florian Gross flgr@ccan.de writes:

Yay, finally we'll be able to use define_method() everywhere where we
would use def instead.

No, and this was your error in [ruby-talk:99984]

Guy Decoux

Mark Hubbart wrote:

  1. What will yield(*) do?
    I would assume the same as currently: it expands to zero arguments,
    becomes yield()

Yes, but does this translate to an empty Values object? What happens
when it is used in assignment or block parameters?

Why would rescoping rules be changed? Currently, when you call
define_method, Class.new, Module.new, etc., the block is rescoped (is
that the right word?) and local variables never leak in. So, assuming
they don’t make a silly change, define_method would be exactly
orthogonal to def…end:

Currently those constructs aren’t identical and that allows us to do
some very interesting stuff. IMHO that behaviour is also a good thing
because it makes blocks very consistent. You also have access to
variables of surrounding scopes in .instance_eval, for example. Here’s
an useless, but interesting example – there are also cases where this
is useful, however.

class Foo
count = 0
define_method(:initialize) do
count += 1
@number = count
end
attr_accessor :number
end

(1…10).map { Foo.new.number } # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Disclaimer: This is only based on the way I read it; I could very likely
be all wet. :slight_smile:

I don’t know – as always, it would be very interesting to know matz’
opinion about all this. :slight_smile:

cheers,
Mark

Regards,
Florian Gross

Hi –

Hi,

Does this mean that:

a,b = b,a

won’t work any more? That it’ll have to be:
a,b = Values( b,a )

No. “b,a” in “a,b = b,a” is a shorthand for “Values(b,a)”.
Note that it is still not the final decision.

I’m being stupid; I don’t understand the whole Values thing.

Is it that b,a is a literal constructor for a Values object (like
and {}, but just bare)?

How would one assign a Values object to a variable? In other words:

a = [1,2] # literal array constructor
b = {1 => 2} # literal hash constructor
c = … # ??

David

P.S. Your messages in this thread don’t seem to have been propagated
to Usenet, so this is now a ruby-talk-only branch of the thread :frowning:

···

On Wed, 26 May 2004, Yukihiro Matsumoto wrote:

In message “Re: ruby-dev summary 23459-23562” > on 04/05/26, “SER” ser@germane-software.com writes:


David A. Black
dblack@wobblini.net

Can you elaborate?

Paul

···

On Wed, May 26, 2004 at 05:52:02PM +0900, ts wrote:

No

I don’t think that’s quite right.

Currently, #define_method is useful for creating methods that capture the
closure of where it’s defined so:

class Foo
a = 4
define_method(:foo) do
puts a
end
end

class Bar
a = 4
def foo
puts a
end
end

Foo.new.foo
Bar.new.foo

Prints “4” for the first call, and causes an error for the second.

Now, scoping is changing in Ruby 2.0. Currently

method {
local = 5
}

is scoped such that local can’t be seen outside the block (assuming that
there is no local defined outside the block). However, in 2.0, it will be
equivalent to:

local = nil
method {
local = 5
}

So variables will automatically leak out of blocks. So in the case of:

define_method(:foo) { bar = 5 }
foo
p bar

You should get 5 printed out (if my understanding is correct).

– Dan

···

On Tuesday 25 May 2004 3:41 pm, Mark Hubbart wrote:

define_method(:foo) { |arg| result = arg }
foo(5); result # => 5 or ~> NameError?

Or more interesting:

define_method(:foo) { foo = nil; return true }
foo # => true or nil or NameError?
foo # => true or nil?

IIUC, the first snippet would give a NameError, the second would return
true twice. That’s the way it is now…

Why would rescoping rules be changed? Currently, when you call
define_method, Class.new, Module.new, etc., the block is rescoped (is
that the right word?) and local variables never leak in. So, assuming
they don’t make a silly change, define_method would be exactly
orthogonal to def…end:

ts wrote:

Yay, finally we’ll be able to use define_method() everywhere where we
would use def instead.

No, and this was your error in [ruby-talk:99984]

What kind of error are you talking about exactly? The code seems to work
fine for me.

Currently it can’t be done without an additional def (because blocks
don’t have block argument slots yet), but it looks as if this would soon
be changed.

Hi –

···

On Wed, 26 May 2004, Florian Gross wrote:

Mark Hubbart wrote:

  1. What will yield(*) do?
    I would assume the same as currently: it expands to zero arguments,
    becomes yield()

Yes, but does this translate to an empty Values object? What happens
when it is used in assignment or block parameters?

I still don’t get where this Values object enters into it. […] is
an Array. The block parameters will be assigned this array (or from
it). The result of the yield will be whatever the block returns.

It seems like the Values object has no opportunity (or reason) to
exist.

David


David A. Black
dblack@wobblini.net

No

Can you elaborate?

Well, don't truncate my messages. I know that I like to write very long
message in anglois, but you can try to quote me a little more :-)))

The initial message was

No, and this was your error in [ruby-talk:99984]

                         ^^^^^ ^^^^^^^^^^^^^^^^^

read this message and find the problem in it

Guy Decoux

···

On Wed, May 26, 2004 at 05:52:02PM +0900, ts wrote:

If I read the initial post correctly

c = 1, 2

Means Values(1, 2) is assigned to c.

If not, then it appears that

c = *[1, 2]

Should definitely have that effect.

Although I’ll admit that I don’t understand the overall purpose of Values
objects other than to have a class that makes argument lists distinct from
arrays (which is important, nonetheless). Will these objects be real and can
code actually manipulate them, or are they more or less internal?

– Dan

···

On Wednesday 26 May 2004 7:30 am, David A. Black wrote:

I’m being stupid; I don’t understand the whole Values thing.

Is it that b,a is a literal constructor for a Values object (like
and {}, but just bare)?

How would one assign a Values object to a variable? In other words:

a = [1,2] # literal array constructor
b = {1 => 2} # literal hash constructor
c = … # ??

I was wrong, as you and someone else pointed out. And I’m pretty sure
you are right. I hadn’t realized that methods defined via blocks
retained their original binding. That’s a very cool thing, and I am
sure I’ll be using it in the future :slight_smile:

At first, I was thinking that that makes scoping very difficult to
understand; then I realized that I just need to dump my old
misunderstandings and figure that the ‘self’ scope and the current
binding are only minimally related.

cheers,
Mark

···

On May 26, 2004, at 3:00 PM, Dan Doel wrote:

On Tuesday 25 May 2004 3:41 pm, Mark Hubbart wrote:

define_method(:foo) { |arg| result = arg }
foo(5); result # => 5 or ~> NameError?

Or more interesting:

define_method(:foo) { foo = nil; return true }
foo # => true or nil or NameError?
foo # => true or nil?

IIUC, the first snippet would give a NameError, the second would
return
true twice. That’s the way it is now…

Why would rescoping rules be changed? Currently, when you call
define_method, Class.new, Module.new, etc., the block is rescoped (is
that the right word?) and local variables never leak in. So, assuming
they don’t make a silly change, define_method would be exactly
orthogonal to def…end:

I don’t think that’s quite right.

Currently, #define_method is useful for creating methods that capture
the
closure of where it’s defined so:

You should get 5 printed out (if my understanding is correct).