Metaprogrammatically defining methods with required, optional, required keyword and optional keyword parameters?

I'm want to do meta programming in the sense of writing ruby to create
a new ruby method.

Module#define_method exists....

   Class: Module (Ruby 2.5.2)

However modern ruby now has required parameters, default parameters,
required keyword parameters and optional keyword parameters and an
optional a block parameter.

So Method.parameters seems to understand all these things....

  > def foo( bar, baz, but = 0, joke:, nojoke: 10, &block);end
=> :foo
  > method(:foo).parameters
=> [[:req, :bar], [:req, :baz], [:opt, :but], [:keyreq, :joke], [:key,
:nojoke], [:block, :block]]

Module#define_method would seem to be what I want.... but... that
defers the problem of specifying the parameters to Proc, Method,
UnboundMethod or block....

Proc.new basically converts a block into a Proc.

Method.new and UnboundMethod.new do not exist.

block's themselves are not quite first class objects.

I guess I could achieve the required magic by Module.class_eval(
string) ... but that seems crude...

Any idea how to define (at run time) the parameter list for a method?

I have done it, somewhat crudely by

         define_method( :my_constructed_at_run_time_method) do

*positional,**keyword|

             # Implement all the parameter checking and raise
ArgumentError in the right places
             # in raw ruby...
        end

..but that seems duplicating all the logic around parameter checking
that must already exist somewhere in the Ruby runtime..

···

--
John Carter
Phone : (64)(3) 358 6639
Tait Electronics
PO Box 1645 Christchurch
New Zealand

--
This Communication is Confidential. We only send and receive email on the

basis of the terms set out at Email to and from Tait Communications | Tait Communications
<http://www.taitradio.com/email_disclaimer&gt;

Here's your example with define_method:

    define_method(:foo) do |bar, baz, but = 0, joke:, nojoke: 10, &block|
      p [bar, baz, but, joke, nojoke, block]
      block.call
    end

    foo(1, 2, joke: 50){puts "I'm a block!"}

Is that what you are looking for?

···

Am 17. Juni 2019 um 10:20 Uhr +1200 schrieb John Carter:

However modern ruby now has required parameters, default parameters,
required keyword parameters and optional keyword parameters and an
optional a block parameter.
[...]
Any idea how to define (at run time) the parameter list for a method?

--
Blog: https://mg.guelker.eu

Yup. That's exactly what I'm looking for. Thanks!

I must be getting old or something...

I have looked up and down Index of Files, Classes & Methods in Ruby 2.5.2 (Ruby 2.5.2) and
Introduction - Ruby Reference and can't see where they say
blocks have those features as well.

Can you anyone put me out of my misery and point me at the Right part of
the FM To R?

···

On Mon, Jun 17, 2019 at 6:58 PM Marvin Gülker <post+rubytalk@guelker.eu> wrote:

Am 17. Juni 2019 um 10:20 Uhr +1200 schrieb John Carter:
> However modern ruby now has required parameters, default parameters,
> required keyword parameters and optional keyword parameters and an
> optional a block parameter.
> [...]
> Any idea how to define (at run time) the parameter list for a method?

Here's your example with define_method:

    define_method(:foo) do |bar, baz, but = 0, joke:, nojoke: 10, &block|
      p [bar, baz, but, joke, nojoke, block]
      block.call
    end

    foo(1, 2, joke: 50){puts "I'm a block!"}

Is that what you are looking for?

--
Blog: https://mg.guelker.eu

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
John Carter
Phone : (64)(3) 358 6639
Tait Electronics
PO Box 1645 Christchurch
New Zealand

--
This Communication is Confidential. We only send and receive email on the

basis of the terms set out at Email to and from Tait Communications | Tait Communications
<http://www.taitradio.com/email_disclaimer&gt;

Ah. Wait, no. That won't quite work.

Because I still cannot programatically create that block at run time.

ie. If instead of giving the parameter list at ruby invocation time,.... I
want at run time to do something very similar to the Struct facility...

def SmartStruct.create_struct_class(
          require_list, # Ordered Hash of positional parameter to expected
class.
          defaults: {}, # Hash of sym: default_value
          required_keyword_list: {}, # Hash of sym: expected class
          keyword_list: {}, # Map from keyword sym to default
          accessors: ) # Array of syms to provide accessors for

I then want to generate a Class that will have the specified parameters and
defaults and will type check them at run time.

···

On Mon, Jun 17, 2019 at 6:58 PM Marvin Gülker <post+rubytalk@guelker.eu> wrote:

Am 17. Juni 2019 um 10:20 Uhr +1200 schrieb John Carter:
> However modern ruby now has required parameters, default parameters,
> required keyword parameters and optional keyword parameters and an
> optional a block parameter.
> [...]
> Any idea how to define (at run time) the parameter list for a method?

Here's your example with define_method:

    define_method(:foo) do |bar, baz, but = 0, joke:, nojoke: 10, &block|
      p [bar, baz, but, joke, nojoke, block]
      block.call
    end

    foo(1, 2, joke: 50){puts "I'm a block!"}

Is that what you are looking for?

--
Blog: https://mg.guelker.eu

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
John Carter
Phone : (64)(3) 358 6639
Tait Electronics
PO Box 1645 Christchurch
New Zealand

--
This Communication is Confidential. We only send and receive email on the

basis of the terms set out at Email to and from Tait Communications | Tait Communications
<http://www.taitradio.com/email_disclaimer&gt;