How to improve this kind of API?

I’m looking to make an API change for some methods in FXRuby and would
appreciate some suggestions about how to improve them. The pattern shows
up
in several places in the code, but it always boils down to some widget
attribute that can have a combination of bit-flags. For example, the
4-way
splitter window can be configured to expand only its top-left pane:

splitter1.expanded = TOP_LEFT

or to expand both the top left and top right panes:

splitter2.expanded = TOP_LEFT | TOP_RIGHT

And to check whether, say, the BOTTOM_LEFT pane is expanded:

(splitter3.expanded & BOTTOM_LEFT) != 0

Now, what I’m thinking of doing is replacing the symbolic constants with
Ruby symbols, and doing something like this instead:

splitter1.expand(:top_left)
splitter2.expand(:top_left, :top_right)

and then having checks like:

splitter3.expanded? :bottom_left

I think that in order to “turn off” one of those bits, I’m probably also
going to need to add something like:

splitter4.unexpand(:bottom_right)

Now, the question is, is there some existing pattern in Ruby that this
reminds you of? In other words, what is the Ruby Way to handle this kind
of
setting?

Thanks in advance for your suggestions!

Lyle

DÅ?a Å tvrtok 09 Február 2006 20:42 Lyle J. napísal:

splitter2.expanded = TOP_LEFT | TOP_RIGHT

reminds you of? In other words, what is the Ruby Way to handle this kind of
setting?

Thanks in advance for your suggestions!

Lyle

Looks fine to me. Personally I wish more GUI toolkits provided
functions/methods like set_flag() and clear_flag() (or the even rarer
explicit getters and setters for all applicable flags) that take flags
that
are to be changed instead having to futz around with unintuitive
catch-all
style flag fields and doing bitwise fandango all the time. Keep up the
food
work.

David V.

David V. wrote:

style flag fields and doing bitwise fandango all the time. Keep up the food
work.

As much as we all love FXRuby, I sure hope Lyle has another source of
food. :wink:

Seriously, it’s great to hear that the FXRuby interface will be getting
more ruby-like. I like Ara’s suggestions for easy configuration from
YAML.load-ed hashes.

On 2/9/06, Simon Kröger [email protected] wrote:

Well, i haven’t used FXRuby very much, so i might miss the problem with
the current interface, but from what i see below i think this new
version doesn’t justify breaking old code.

OK.

For example, the 4-way
splitter window can be configured to expand only its top-left pane:

splitter1.expanded = TOP_LEFT

Seems perfectly fine. Ok :top_left if more ruby’ish but also more
dangerous.

Why do you consider it more dangerous to use a symbol in place of a
symbolic constant? Is it that Ruby would “notice” that a constant’s
name is erroneous (e.g. misspelling TOP_LEFT as TOPLEFT), but wouldn’t
notice if you made the same mistake for a symbol or string (e.g.
misspelling “top_left” as “topleft”)?

The following isn’t meant to be ‘the soultion’ but perhaps food for
thoughts:

Thanks. I need to ponder this…

Lyle J. wrote:

I’m looking to make an API change for some methods in FXRuby and would
appreciate some suggestions about how to improve them. The pattern shows up
in several places in the code, but it always boils down to some widget
attribute that can have a combination of bit-flags.

Well, i haven’t used FXRuby very much, so i might miss the problem with
the current interface, but from what i see below i think this new
version doesn’t justify breaking old code.

For example, the 4-way
splitter window can be configured to expand only its top-left pane:

splitter1.expanded = TOP_LEFT

Seems perfectly fine. Ok :top_left if more ruby’ish but also more
dangerous.

or to expand both the top left and top right panes:

splitter2.expanded = TOP_LEFT | TOP_RIGHT

Also fine. Perhaps define a TOP constant for those who don’t like binary
operations.

And to check whether, say, the BOTTOM_LEFT pane is expanded:

(splitter3.expanded & BOTTOM_LEFT) != 0

Ok, agreed, this isn’t very nice.

Now, what I’m thinking of doing is replacing the symbolic constants with
Ruby symbols, and doing something like this instead:

splitter1.expand(:top_left)
splitter2.expand(:top_left, :top_right)

Well, i don’t like using 2 parameters when it is only one logically.

and then having checks like:

splitter3.expanded? :bottom_left

I don’t like that either.

I think that in order to “turn off” one of those bits, I’m probably also
going to need to add something like:

splitter4.unexpand(:bottom_right)

Oh, and i realy dislike this.

Now, the question is, is there some existing pattern in Ruby that this
reminds you of? In other words, what is the Ruby Way to handle this kind of
setting?

The following isn’t meant to be ‘the soultion’ but perhaps food for
thoughts:

require ‘set’

class Symbol
def method_missing meth, *param
set = Set[self]
set.send meth, param.to_a if set.respond_to?(meth)
end
end

class Splitter
attr_accessor :expanded
end

TOP_LEFT = :top_left
TOP_RIGHT = :top_right
BOTTOM_LEFT = :bottom_right
BOTTOM_RIGHT = :bottom_right

splitter = Splitter.new

splitter.expanded = TOP_LEFT
p splitter.expanded
#=> :top_left

splitter.expanded = TOP_LEFT | TOP_RIGHT
p splitter.expanded
#=><Set: {:top_right, :top_left}>

p splitter.expanded.include?(BOTTOM_LEFT)
#=> false

p splitter.expanded.include?(TOP_LEFT)
#=> true

splitter.expanded = :bottom_left | :top_left
p splitter.expanded
#=> #<Set: {:bottom_left, :top_left}>

splitter.expanded.delete(:top_left)
p splitter.expanded
#=> #<Set: {:bottom_left}>

cheers

Simon

DÅ?a Å tvrtok 09 Február 2006 21:33 Joel VanderWerf napísal:

David V. wrote:

style flag fields and doing bitwise fandango all the time. Keep up the
food work.

As much as we all love FXRuby, I sure hope Lyle has another source of
food. :wink:

I cnt saem to tyep tpday…