Procs and blocks


(Jean-Hugues ROBERT) #1

Hello,

About: Extracting optional parameters

I checked the docs:

Apparently foo = (opt && opt.include? :foo) ? opt[:foo] : <def_foo>
is eqv to: foo = opt.fetch( :foo) {<def_foo>} # eval <def_foo> if needed
and ~ to: foo = opt.fetch( :foo, <def_foo>) # always eval <def_foo>

… that’s slightly more compact, but maybe less efficient… to double
check

Yours,

Jean-Hugues

Hello, I’m new to ruby, coming from Python (et al).

Therefore my question:

Jean-Hugues ROBERT schrieb:

The main drawback is that optional parameters become mandatory when
one want to use Proc object instead of block:
def err( msg = “Err”, b = nil, &sb )
b = sb if sb
b( msg)
end
a = Proc.new do |x| print x end
err do |x| print x end
err “Hello” do |x| print x end
err “Hello”, a
err( , a) # Not in Ruby syntax…

This seems to indicate me that 'named parameters’
are missing, which are possible in Python
(and do attract me)?

With that the last line would read:
err (b=a)

Ok, in Ruby there should be an alternative syntax,
as this one causes another result (and is supposed to).

No such thing yet. It is planned however.

In the mean time, the idiom seems to be to use a hash, with some
help from Ruby:

a( x,y, :foo => “hello”, :bar => “world”)
which is syntax sugar for:
a( x, y, {:foo => “hello”, :bar => “world”}).

a() needs to be something like:
def a( x, y, opt = nil )
foo = (opt && opt.include? :foo) ? opt[:foo] : <def_foo>
bar = (opt && opt.include? :bar) ? opt[:bar] : <def_bar>
xxx
end

BTW: I proposed a syntax sugar for hashes:
a( x, y, foo: “hello”, bar: “world”)
eqv a( x, y, :foo => “hello”, :bar => “world”) # already sugar
eqv a( x, y, {:foo => “hello”, :bar => “world”}) # final

On the callee side, one could enjoy:
def a( x, y, foo:, far: “Hello”) # foo defaults to nil, bar to “Hello”

Still an open subject I guess.

Yours,

Jean-Hugues

···

At 20:20 13/06/2002 +0900, you wrote:


(Dirk Detering) #2

Regarding trailing colon as Hash syntax sugar in general:

Not only for optical reasons, but the colon notation
(which is used for hashes (dictionaries) in python too)
is much better to type than the => .

On englisch kb layouts you have to type one key in
the most upper row and one in the lowest row with shift,
both in one hand.
On german kb though you can type both with the shift key
pressed, you find one char in the upper right corner,
the other in the lower left.

However, it is annoying if you try to initialize
a hash with some more values.

Regarding named parameters:

Jean-Hugues ROBERT wrote:

BTW: I proposed a syntax sugar for hashes:
a( x, y, foo: “hello”, bar: “world”)
[…]
On the callee side, one could enjoy:
def a( x, y, foo:, bar: “Hello”) # foo defaults to nil,
bar to “Hello”

Looks both very good to me!

Regarding current ways to extract optional parameters:

Apparently foo = (opt && opt.include? :foo) ? opt[:foo] : <def_foo>
is eqv to: foo = opt.fetch( :foo) {<def_foo>}

Is it?
In the ‘Apparently’-line you checked for existence of opt first,
but you omitted that in the second version (?).

AFAIU the parameter should not be initialized to nil,
like you suggested before …

a() needs to be something like:
def a( x, y, opt = nil )
foo = (opt && opt.include? :foo) ? opt[:foo] : <def_foo>
[…]

… but to an empty hash, as you expect a hash to be given
by the user of your method:

def a( x, y, opt = {} )

Shouldn’t it?

Bye
Dirk Detering - aka Det