ruby-dev summary 23459-23562

M

Minero Aoki

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
 
D

David Alan Black

Hi --

Minero Aoki said:
[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 :)
[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 :) 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
 
M

Mauricio Fernández

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 :)

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

--
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
 
P

Paul Brannan

* `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
 
F

Florian Gross

Minero said:
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
 
M

Mark Hubbart

Minero said:
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()
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?

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

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

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. :)

cheers,
Mark
 
F

Florian Gross

Mark said:
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. :)

I don't know -- as always, it would be very interesting to know matz'
opinion about all this. :)
cheers,
Mark

Regards,
Florian Gross
 
D

David A. Black

Hi --

Mark said:
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
 
G

gabriele renzi

[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)

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]
 
T

ts

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

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


Guy Decoux
 
F

Florian Gross

ts said:
F> Yay, finally we'll be able to use define_method() everywhere where we
F> 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.
 
T

ts

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

You've not seen my message on ruby-talk

svg% ls b.rb x.rb
ls: x.rb: No such file or directory
b.rb*
svg%

svg% cat b.rb
#!/usr/bin/ruby
ObjectSpace.module_eval do
class << self
old_finalizer = instance_method:)define_finalizer)
define_method:)_define_finalizer) do |block, *args|
p $SAFE
raise(SecurityError, "Penalizing finalizing") if $SAFE > 1
old_finalizer.bind(self).call(*args, &block)
end
def define_finalizer(*args, &block)
_define_finalizer(block, *args)
end

alias :add_finalizer :define_finalizer
end
end

$SAFE = 4

class << s = "`mv b.rb x.rb`"
def call
end
end
a = Object.new
ObjectSpace.define_finalizer(a, s)
svg%

svg% b.rb
0
svg%

svg% ls b.rb x.rb
ls: b.rb: No such file or directory
x.rb*
svg%

it run with $SAFE = 4 but I've still the possibility to define a
finalizer
 
F

Florian Gross

ts said:
it run with $SAFE = 4 but I've still the possibility to define a
finalizer

And that's because the define_method-block has its own version of $SAFE
which is still 0?
 
T

ts

F> And that's because the define_method-block has its own version of
F> $SAFE which is still 0?

Yes, define_method store the block in a Proc object which preserve the
value of $SAFE. When the proc is called, it restore the value of $SAFE to
its original value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,105
Latest member
sheetaldubay7750ync
Top