Public/protected/private syntax

Hi,

Once I decide, it would cost me a few minutes. But we have to discuss
and get consensus about what “def” returns (is Symbol OK for you guys?).

What would be the impact of having it return an unbound method? Is there
any way to optimize this so that it only generates the return object if
it knows that it is being used?

Since Ruby doesn’t preserve UnboundMethod internally (it creates
method objects every time they’re requested), the modification would
be far bigger. Probably you have to wait until Rite.

Don’t they already return the value of the last statement executed? This
seems to be a Good Thing, as it is flexible. This way of doing things
obviously doesn’t apply to ‘def’, which doesn’t execute its body at
‘compile’ time.

Yep. But when “def” returns UnboundMethod, I’m afraid many would
expect “class” to return Class objects.

						matz.
···

In message “Re: public/protected/private syntax” on 03/05/20, Dave Thomas dave@pragprog.com writes:

Yukihiro Matsumoto wrote:

Yep. But when “def” returns UnboundMethod, I’m afraid many would
expect “class” to return Class objects.

I can see that, but the two are really very different things, so we’d
need to document the fact clearly.

With classes, we could have a slight compromise: anonymous classes (ie
those without a constant name following the keyword ‘class’) could
return a class object, while more conventional classes do what the
current implementation does and return the last statement. That would
let us do things like

 Fred = class
    def m1
    end
 end

and

 set_listener_type(class
                     def trigger
                       ...
                     end
                   end)

we could then have anonymous method definitions too. Regular methods
return a symbol, and anonymous methods return an UnboundMethod

 private def fred
   ...
 end

 dave = def(a,b)
    a + b
 end

This would be a step towards rationalizing the proc/method issue.

If this was the long-term plan, we could then do the first step and have
regular methods return a symbol, which is a relatively small change and
one that won’t break anything.

Cheers

Dave

“Dave Thomas” dave@pragprog.com schrieb im Newsbeitrag
news:3EC92A0F.6070003@pragprog.com

we could then have anonymous method definitions too. Regular methods
return a symbol, and anonymous methods return an UnboundMethod

 private def fred
   ...
 end

 dave = def(a,b)
    a + b
 end

This would be a step towards rationalizing the proc/method issue.

If this was the long-term plan, we could then do the first step and have
regular methods return a symbol, which is a relatively small change and
one that won’t break anything.

I was just going to write something along these lines.

<think_loud>I’d just like to add that the return value of “def” should be
something that allows to access the method just generated. I guess Dave’s
suggestions ensure exactly this.

Maybe an alternative to the UnboundMethod instance (if that’s too expensive)
would be an object id of the would be created UnboundMethod instance that
could be used to retrieve the instance if needed. But then, what exactly
might be the operatons we want to perform with an anonymous method - apart
from invoking it?</think_loud>

Cheers

robert

we could then have anonymous method definitions too. Regular methods
return a symbol, and anonymous methods return an UnboundMethod

 private def fred
   ...
 end

 dave = def(a,b)
    a + b
 end

This would be a step towards rationalizing the proc/method issue.

Then the only differences between anonymous methods and procs would be
the argument passing semantics and the fact that a method needs to be
bound, am I right? Will we want to keep both “yield” and “method”
semantics forever, or will say “yield” be phased out?

What about UnboundMethod instances passed as blocks being automatically
bound to self on #call or yield?

class Foo
def do(*args)
yield(*args)
end
def bar
puts “Foo#bar”
end
end

f = def; bar end

Foo.new.do f # => Foo#bar

Maybe it’s not such a good idea because we’d have to document the
expected arg. semantics for each method receiving a block…

Maybe an alternative to the UnboundMethod instance (if that’s too expensive)
would be an object id of the would be created UnboundMethod instance that
could be used to retrieve the instance if needed. But then, what exactly
might be the operatons we want to perform with an anonymous method - apart
from invoking it?</think_loud>

arity

?

···

On Tue, May 20, 2003 at 06:08:35AM +0900, Robert wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Actually, typing random strings in the Finder does the equivalent of
filename completion.
– Discussion on file completion vs. the Mac Finder

“Mauricio Fernández” batsman.geo@yahoo.com schrieb im Newsbeitrag
news:20030520062014.GA15138@student.ei.uni-stuttgart.de

we could then have anonymous method definitions too. Regular methods
return a symbol, and anonymous methods return an UnboundMethod

 private def fred
   ...
 end

 dave = def(a,b)
    a + b
 end

This would be a step towards rationalizing the proc/method issue.

Then the only differences between anonymous methods and procs would be
the argument passing semantics and the fact that a method needs to be
bound, am I right?

I thought that a proc is bound also:

irb(main):001:0> class Foo
irb(main):002:1> def get
irb(main):003:2> proc { self }
irb(main):004:2> end
irb(main):005:1> end
nil
irb(main):006:0>
irb(main):007:0* f1 = Foo.new
#Foo:0x2ab1138
irb(main):008:0> p1 = f1.get
#Proc:0x02aaeb40@:3(irb)
irb(main):009:0> f2 = p1.call
#Foo:0x2ab1138
irb(main):010:0> f2.equal? f1
true
irb(main):011:0>
irb(main):012:0* m1 = f1.method :get
#<Method: Foo#get>
irb(main):013:0> p2 = m1.call
#Proc:0x02a519d0@:3(irb)
irb(main):014:0> f3 = p2.call
#Foo:0x2ab1138
irb(main):015:0> f3.equal? f1
true
irb(main):016:0>
irb(main):017:0* p1.public_methods - m1.public_methods
[“yield”, “binding”]
irb(main):018:0> m1.public_methods - p1.public_methods
[“unbind”]
irb(main):019:0>

Now I’m starting to get confused: What was the difference between a Method
and a Proc?

Will we want to keep both “yield” and “method”
semantics forever, or will say “yield” be phased out?

What about UnboundMethod instances passed as blocks being automatically
bound to self on #call or yield?

Interesting thought. However, I’d keep “yield”, because it does not need
an explicit reference to the block - and it’s kind of at the heart of
Ruby…

class Foo
def do(*args)
yield(*args)
end
def bar
puts “Foo#bar”
end
end

f = def; bar end

Foo.new.do f # => Foo#bar

Maybe it’s not such a good idea because we’d have to document the
expected arg. semantics for each method receiving a block…

But don’t we do that already with blocks given to “each”,
“each_with_index” etc.?

Maybe an alternative to the UnboundMethod instance (if that’s too
expensive)
would be an object id of the would be created UnboundMethod instance
that
could be used to retrieve the instance if needed. But then, what
exactly
might be the operatons we want to perform with an anonymous method -
apart
from invoking it?</think_loud>

arity

Yeah, that’s right.

robert
···

On Tue, May 20, 2003 at 06:08:35AM +0900, Robert wrote:

Then the only differences between anonymous methods and procs would be
the argument passing semantics and the fact that a method needs to be
bound, am I right?

I thought that a proc is bound also:

It is indeed, in the sense that ‘self’ and locals used inside are
captured (that’s the “closure” part).

Now I’m starting to get confused: What was the difference between a Method
and a Proc?

Well, when I said that “a method needs to be bound” I was thinking of
UnboundMethod:

class Foo; def foo; puts “Foo#foo”; end; end
=> nil
meth = Foo.instance_method(:foo)
=> #<UnboundMethod: Foo(Foo)#foo>
meth.call
TypeError: you cannot call unbound method; bind first
from (irb):3:in `call’
from (irb):3
a = Foo.new
=> #Foo:0x4020fda0
meth.bind(a).call
Foo#foo
=> nil

With the proposal under consideration, that and the argument passing
semantics would be the only differences, I believe.

def meth(a)
p a
end
=> nil
pp = proc { |a| p a }
=> #Proc:0x40187938
meth(1,2,3)
ArgumentError: wrong # of arguments(3 for 1)
from (irb):5:in `meth’
from (irb):5
pp.call(1,2,3)
[1, 2, 3]
=> nil

etc

Will we want to keep both “yield” and “method”
semantics forever, or will say “yield” be phased out?

What about UnboundMethod instances passed as blocks being automatically
bound to self on #call or yield?

Interesting thought. However, I’d keep “yield”, because it does not need
an explicit reference to the block - and it’s kind of at the heart of
Ruby…

I was thinking of not needing a reference to the block :slight_smile:
My idea was the following:

1.times def
puts “bla”
end # => bla

def twice
yield
yield
end

twice def
puts “bla” # => bla
end # bla

twice def(a)
puts a
end
ArgumentError: wrong # of arguments(0 for 1)

So the method passing semantics are defined by the “e-block” (extended
block, meaning either proc or UnboundMethod) passed. Then we can have
yield and something else for symmetry. More info in [ruby-talk:70189]

There’s one problem though
a = def; p “aa”; end
twice a # should this work?

def twice(o)
yield o
yield o
end

twice “foo” do |x| p x; end
twice “foo” def(x) p x; end # should this work???

ie. is this twice(“foo”, aMethod) or twice(“foo”, &block)?

solutions:

  • mandatory ‘()’ with def, significant linebreak

    twice(“foo”) def(x)

    end

    but
    twice(“foo”) # LocalJumpError: no block given
    def(x) end

  • using & as with Proc
    twice “foo” &def(x) p x; end

I prefer the second one, it makes sense to always use ‘&’ to turn a real
“Block” object into an “internalized” block.

Maybe it’s not such a good idea because we’d have to document the
expected arg. semantics for each method receiving a block…

But don’t we do that already with blocks given to “each”,
“each_with_index” etc.?

We document the arguments passed, but

(0…3).each_with_index{ |a| p a }
[0, 0]
[1, 1]
[2, 2]
[3, 3]
=> 0…3
(0…3).each_with_index{ |a,| p a }
0
1
2
3

ie. we have assignment semantics.

···

On Tue, May 20, 2003 at 04:31:05PM +0900, Robert Klemme wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

The documentation is in Japanese. Good luck.
– Rich $alz

Hi,

···

In message “Re: public/protected/private syntax” on 03/05/20, Mauricio Fernández batsman.geo@yahoo.com writes:

ie. we have assignment semantics.

But we will get warnings since today’s check in.

						matz.