A comparison by example of keyword argument styles

From: Trans [mailto:transfire@gmail.com]
Sent: Friday, October 21, 2005 8:12 AM
To: ruby-talk ML
Subject: Re: A comparison by example of keyword argument styles

<snip>

Perhaps we should just sing a song and "Let's Call The Whole
Thing Off".

Heh. Thought about it.

If keywords integrate the interface too tightly
with the code, then why tie them to the interface? Also, I
imagine there many be many more keyword arguments then
ordered args, this will make for some very LONG constructors:

  def stadium( height:, seating_capacity:, location:, color:,
sports:, concessions:, extra_features:, indoor:, yadayadayada: )

So maybe just treat named parameters like blocks. You can
have em or not. But you don't need to define them in the
interface. Currently I do a lot of

  def( *args )
    keys = args.last.is_a?(Hash) ? args.pop : {}
    a,b,c = *args

If I could just do

  def( a, b, c, **keys )
    ...

I'd be happy enough.

I'm glad you brought this example up. What do you do when you have a
ton of accessors in your class? I have just such a case with the Format
class in the spreadsheet package, where you have "font_name",
"font_size", "border_color", etc. About 30 accessors I think.

The solution here is NOT keywords arguments (regardless of
implementation), where you would end up with ridiculously long
constructors, as you mentioned. It's the old "yield self if
block_given?" trick:

class Format
   attr_accessor :font_color, :font_size, :bold # ...
   def initialize
      yield self if block_given?
   end
end

format = Format.new do |f|
   f.font_color = "blue"
   f.font_size = 10
   f.bold = true
   ...
end

Regards,

Dan

···

-----Original Message-----

> From: Trans [mailto:transfire@gmail.com]
> Sent: Friday, October 21, 2005 8:12 AM
> To: ruby-talk ML
> Subject: Re: A comparison by example of keyword argument styles

<snip>

> If keywords integrate the interface too tightly
> with the code, then why tie them to the interface? Also, I
> imagine there many be many more keyword arguments then
> ordered args, this will make for some very LONG constructors:
>
> def stadium( height:, seating_capacity:, location:, color:,
> sports:, concessions:, extra_features:, indoor:, yadayadayada: )

<snip>

I'm glad you brought this example up. What do you do when you have a
ton of accessors in your class? I have just such a case with the Format
class in the spreadsheet package, where you have "font_name",
"font_size", "border_color", etc. About 30 accessors I think.

The solution here is NOT keywords arguments (regardless of
implementation), where you would end up with ridiculously long
constructors, as you mentioned. It's the old "yield self if
block_given?" trick:

class Format
   attr_accessor :font_color, :font_size, :bold # ...
   def initialize
      yield self if block_given?
   end
end

format = Format.new do |f|
   f.font_color = "blue"
   f.font_size = 10
   f.bold = true
   ...
end

Has any thought been given to defining the parameters and keywords
using something similar to attr_accessor? Seems that would reduce the
long constructor problem, and would be fairly developer friendly.

It's always seemed strange to me that the two formats differ, seems a
nuisance when you've built up either the attr_accessor list, or your
parameter list, and you have to hand massage one to the other.

class Format
  attr_accessor :font_face, :font_color, :font_size, :bold, :italic
  def initialize
    parameters :font_face='arial'
    keywords :font_color='black', :font_size, :bold=false, :italic=false
    ...
  end
end

format = Format.new('verdana')
format = Format.new(font_size: 1, bold: true)
format = Format.new('verdana', italic: true, font_size: 10)

granted, functon calls and constructors could still get quite lengthy.

disclaimer: this is not a thought that I'm in love with, just one that
crossed my mind.

Regards,

Dan

[OT] many thanks to those who put together the conference, and the videos.

···

On 10/21/05, Berger, Daniel <Daniel.Berger@qwest.com> wrote:

> -----Original Message-----

--
Bill Guindon (aka aGorilla)

Bill Guindon wrote:

It's always seemed strange to me that the two formats differ, seems a
nuisance when you've built up either the attr_accessor list, or your
parameter list, and you have to hand massage one to the other.

class Format
  attr_accessor :font_face, :font_color, :font_size, :bold, :italic
  def initialize
    parameters :font_face='arial'
    keywords :font_color='black', :font_size, :bold=false, :italic=false
    ...
  end
end

format = Format.new('verdana')
format = Format.new(font_size: 1, bold: true)
format = Format.new('verdana', italic: true, font_size: 10)

granted, functon calls and constructors could still get quite lengthy.

But you can mitigate that. Also there's no need for this on regular
parameters, they can remain pretty much the same, though something like
this might be nice default values. Anyway:

class Format
   attr_accessor :font_face, :font_color, :font_size, :bold, :italic
   def initialize(font_face='arial')
     key :font_color=>'black'
     key :font_size
     key :bold=>false
     key :italic=>false
     ...
   end
end

or just

class Format
   attr_accessor :font_face, :font_color, :font_size, :bold, :italic
   def initialize(font_face='arial')
     keys :font_size,
          :font_color=>'black',
          :bold=>false,
          :italic=>false
     ...
   end
end

Though I am not using the new named parameters for the #keys method
itself here. Even so this is kind of nice. It's kind of like the lisp
stuff too. And in a way it's like a "keywords block", in fact:

class Format

   attr_accessor :font_face, :font_color, :font_size, :bold, :italic

   def initialize(font_face='arial') keys :font_size,
                                          :font_color=>'black',
                                          :bold=>false,
                                          :italic=>false
     puts "keeps the keys out ot the paranthetical"
   end

end

The only things is that means key/keys becomes a keyword (no pun
intended). At least I think it would. Well, in that case we could take
it a bit further and pull a page out of Alex' book -- it might be even
nicer to predefine these keys:

class Format

   attr_accessor :font_face, :font_color, :font_size, :bold, :italic

   initkeys = keys :font_size,
                   :font_color=>'black',
                   :bold=>false,
                   :italic=>false

   def initialize( font_face='arial', *initkeys )
     puts "keeps the keys out ot the paranthetical"
   end

end

Then they be reusable. Could extend this to parameters in general too.

T.