Reputation: 752
Would it be bad practice to have a method that returns self
on block_given?
and a different type if a block was not provided?
The example:
Config#item
will return the item
if a block is not given, and will return Config
if it is given.
class Item
:attr_reader :key
def initialize(key)
@key = key
end
def do_stuff
puts "#{key} doing some stuff"
self
end
end
class Config
attr_reader :items
def initialize
@items = {}
end
def item(key)
itm = @items[key] ||= Item.new(key)
if block_given?
yield(itm)
self
else
itm
end
end
end
Usage:
cnf = Config.new
cnf.item("foo") do |itm|
itm.do_stuff
end
.item("bar") do |itm|
itm.do_stuff
end
foo = .item("foo").do_stuff
cnf.item("baz").do_stuff
foo.do_stuff
The model is meant to use the same method item
as a getter and as a way to refer to an item that needs to be configured or which configuration needs to be reopened.
Upvotes: 0
Views: 254
Reputation: 8042
Not at all, as long as the users of your method have adequate understanding of this. Documentation helps quite significantly in these situations.
Consider the Ruby Standard Library. Many methods return different types based on their inputs and block_given?
, such as Enumerable#map
, Hash#each
, and Range#step
.
Like the standard library authors, you have to decide whether you prefer a compact interface to your class/model or consistent behavior from your methods. There are always tradeoffs to make, and you have numerous strong examples of each of these to draw from within the Ruby Standard Library.
Upvotes: 2
Reputation: 369624
Would it be bad practice to have a method that returns
self
onblock_given?
and a different type if a block was not provided?
No. In fact, there is an extremely well-known example of a method that has this exact signature: each
. each
returns self
if a block is given, and an Enumerator
when no block is given. In fact, many methods in Enumerable
return an Enumerator
when no block is given and something else if there is a block.
(I am actually surprised that you haven't encountered each
or Enumerable
so far.)
Upvotes: 2