Forum: Ruby-core [ruby-trunk - Feature #8629][Open] Method#parameters should include the default value

2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-12 15:16
(Received via mailing list)
Issue #8629 has been reported by rosenfeld (Rodrigo Rosenfeld Rosas).

----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
644bcc0c58aa01920c4de4f941afcac9?d=identicon&s=25 Yorick Peterse (Guest)
on 2013-07-12 15:19
(Received via mailing list)
How would this take dynamic default values into account such as the
following?:

     def some_method(time = Time.now)

     end

Unless UnboundMethod#parameters would re-query this information on every
call I don't see how it would be able to handle this.

Yorick
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-12 15:22
(Received via mailing list)
Issue #8629 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


This would avoid the need of hacks like this one:
https://github.com/wycats/merb/blob/master/merb-ac...
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40474

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles Nutter (headius)
on 2013-07-12 15:41
(Received via mailing list)
Issue #8629 has been updated by headius (Charles Nutter).


I could see this being valid if it were limited to showing literal types
when the default value is a literal and something like :expression when
it's anything more complex (though that obviously isn't the right choice
since :expression as a default value is a perfectly-value literal.

For non-literals (and by literals I mean values that could safely be
evaluated outside the context of that method... strings, symbols,
floats, fixnums, bignums, true/false/nil) there's no real way to
determine the type since it will depend on a method call, a constant
lookup, or in the case of arrays and hashes, the elements contained
within.

It would also not be possible to know whether the default value could
safely be evaluated if it contained *any* constant lookups or method
calls, since they may require being within the activation of that method
(scoping, self methods, etc).
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40476

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-12 16:24
(Received via mailing list)
Issue #8629 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


Yorick, I believe I used exactly your case in my first example, didn't
I? In that case, Method#parameters wouldn't evaluate Time.now but return
a proc instead. It's up to the framework to decide if it will call the
proc or not...

Charles, I understand your concerns, but if the framework explains how
the default arguments are handled I think we should be fine.

For example, suppose the web framework states in the controller's
documentation that this is how it performs the binding:

"""
be aware that any default expression in the argument defaults will be
evaluated twice. The framework will evaluate it once to determine how it
should perform the binding and it will evaluate it once more the method
is called. Keep that in mind when deciding which expressions to use in
default values. In case the default proc raises an exception when called
by the web framework, no special binding rule will be set for that
param. For instance:

def an_action(a=1, b=a+1)
end

In that case, the param "a" is guaranteed to be bound to an Integer
while no binding will occur for param "b".
"""

Do you see? It's up to the frameworks making use of the arguments
default values to decide upon calling the proc or not.

I'm interested in hearing any other considerations from you.
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40477

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
644bcc0c58aa01920c4de4f941afcac9?d=identicon&s=25 Yorick Peterse (Guest)
on 2013-07-12 16:35
(Received via mailing list)
Hm, seems I missed that part. Having said that, I think Charles makes a
valid point in just returning something like `:expression` instead.
There would probably be overhead to storing the actual values (be it as
a Proc or something else).

Yorick

p.s. Note that I fully support this feature request since it would be
neat to have this information (or at least a part of it) available.
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-12 17:03
(Received via mailing list)
Issue #8629 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


I'm not sure if returning a proc instead of something else would be
really an overhead... And the fact that it is a proc is enough for the
application using Method#parameters to ignore it if it doesn't want to
perform any additional checks...

I just find that returning a proc instead of something else would be
generally more useful and allow code to do smarter things with it...
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40479

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 matz (Yukihiro Matsumoto) (Guest)
on 2013-07-27 09:43
(Received via mailing list)
Issue #8629 has been updated by matz (Yukihiro Matsumoto).

Status changed from Open to Rejected

There can be a default value expression that refers external scope, e.g.

  def foo(a, b=a+2)
  end

In the case like this, there's no way to define a proc to return the
default value.
So your proposal is theoretically impossible in general, except for some
cases (say literals),
and I don't want to introduce special cases here.

Matz.


----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40715

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Rejected
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-27 14:08
(Received via mailing list)
Issue #8629 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


I don't understand, I've expressed already my opinion on how it should
behave in the case you pointed out directly in the description. In such
cases you could return a proc as ->{raise UnstranslatableExpression} or
something like that and it would be fine to me.

Could you please reconsider?
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40716

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Rejected
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 matz (Yukihiro Matsumoto) (Guest)
on 2013-07-29 03:19
(Received via mailing list)
Issue #8629 has been updated by matz (Yukihiro Matsumoto).


The option expression can be very complex. IMHO covering simplest cases
does not help.
Besides that, providing proc would introduce huge complexity.  I don't
think proposed incomplete proc behavior is not worth complexity.

Matz.

----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40744

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Rejected
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 rosenfeld (Rodrigo Rosenfeld Rosas) (Guest)
on 2013-07-29 14:50
(Received via mailing list)
Issue #8629 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).


Ok, thanks for considering. I'll try to think in other approaches to
deal with params bindings to propose to the Rails web framework, but
that won't be as elegant as having the binding rules extracted directly
from the default values (since in those cases the default values
wouldn't be a proc if the users read the documentation).
----------------------------------------
Feature #8629: Method#parameters should include the default value
https://bugs.ruby-lang.org/issues/8629#change-40750

Author: rosenfeld (Rodrigo Rosenfeld Rosas)
Status: Rejected
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version:


def a_method arg1=1, now = Time.now, arg2 = arg1 + 1
end

method(:a_method).parameters == [[:opt, :arg1], [:opt, :now], [:opt,
:arg2]]

I'd prefer if it could return [[:opt, :arg1, 1], [:opt, :now, now_proc],
[:opt, :arg2, arg2_proc]], and expect now_proc[] to be the current time
and arg2_proc[] to raise an exception since arg1 is not defined.

Rationale:

Ruby doesn't support optional typing such as:

def a_method Date date, Integer n = 0, String name = ''
end

Groovy does, and this allows Grails to perform some interesting stuff,
like params binding in controller methods.

If Ruby allowed the default values to be introspected, web frameworks
would be able to achieve a similar binding feature. For example, they
could use the default to decide upon how to bind the param. They could
use the default_value.class or if the default value is nil it could be
specified by providing the class itself. For instance:

def an_action name: '', parent_name: String, age: Integer, date:
Date.today
end

Of course, you'd need to set up the framework so that it knows how you
intend parse dates and other special types from string, but this could
make the developer life easier and safer against this kind of attack
(like trying to instantiate a hash, etc).

An alternative would be something like:

def an_action params = {name: :string, age: :integer, date: :date}
end

You get the idea. Many APIs would be possible to be built if we're able
to easily get access to the default values when inspecting a method.

Could you please consider this idea?
76a777ff80f30bd3b390e275cce625bc?d=identicon&s=25 Akira Matsuda (Guest)
on 2013-07-29 16:23
(Received via mailing list)
Rodrigo,

Here's my implementation of "params bindings to propose to the Rails web
framework", which might interest you.
https://github.com/asakusarb/action_args/blob/mast...
Also, here's the craziest example of "other approaches", which might
just
entertain you (I mean, you might not want to use it in your actual
code).
https://speakerdeck.com/a_matsuda/ruby-2-dot-0-on-...
HTH


On Mon, Jul 29, 2013 at 9:50 PM, rosenfeld (Rodrigo Rosenfeld Rosas) <
2abdb50caf0dc5b510330f68b02db8e4?d=identicon&s=25 Rodrigo Rosenfeld Rosas (Guest)
on 2013-07-29 16:47
(Received via mailing list)
Hi Akira, thanks for your valuable input.

While your gem action_args is indeed interesting, it's not quite what
I'm looking for since it will only bind the params to argument variables
but won't perform any type conversion from string, which is what I'm
mostly interested in.

With regards to your slide, I've seen some crazy implementations in the
past (as used by Merb) to try to get the default values or the arguments
as well. I mean, it's definitely easier with Ruby 2.0.0, but still looks
like a bit of Voodoo. That's why I created this ticket so that we
wouldn't need those complicated implementation attempts just to get
access to the default values for the arguments.

It would be much easier if we had an easier way to get access to the
default values (using both the new hash-like syntax or the old one) even
if it's not possible to get the default value in some cases...

Cheers,
Rodrigo.

Em 29-07-2013 11:21, Akira Matsuda escreveu:
This topic is locked and can not be replied to.