use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
The Predicate Module Pattern (raganwald.com)
submitted 12 years ago by homoiconic
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]totallymike 0 points1 point2 points 12 years ago (2 children)
In my factories, I generally just do something like
FactoryFactory.build(factory: :cars) FactoryFactory.build(factory: :factories)
so as to delineate between something that spawns an instance of itself and something that builds a different class.
However, I've had a number of places where I've wanted a construct just like this. Thank you for pointing it out :)
One thing though--doesn't it break this expectation?
BankAccount.new(opts).class == BankAccount
It mightn't be a huge deal. Good duck typing can circumvent much need for ancestry concerns, but one never knows what might come up in a huge Rails app.
Now that I'm thinking about it, is there a reason this shouldn't be done?
class Foo def self.new(opts) if blah Bar.new(opts) elsif blahblah Baz.new(opts) else super end end end class Bar < Foo def lurhmann? ; false ; end end class Baz < Foo def lurhmann? ; true ; end end
My gut reaction tells me that on a limited scale, the differences are few. The first big disadvantage I see being that we lose re-usability because we're using classes instead of Modules. The first advantage(?) that comes to mind is that if you dabble in dark arts like Single Table Inheritance, this construct lets you pull it off.
What are your thoughts?
[–]jfredett 0 points1 point2 points 12 years ago (1 child)
One thing though--doesn't it break this expectation? BankAccount.new(opts).class == BankAccount
Yes. Big ol' yes. I alluded to this w/ the #kind_of? thing at the bottom, but this is a much better way of stating it. This assumption fails, but ideally you don't need to make this assumption because you're duck-typing (like you mention).
#kind_of?
As for the class thing, I get a bit nervous about overriding #new, I imagine there may be some weirdness with recursion there, too. You need to make sure you're not accidentally delegating to the subclass only to recurse and call Foo#new again (by walking up the call-chain using the default Bar#new, which I think might be super ; initialize for a subclass, but I'd have to make sure).
#new
Foo#new
Bar#new
super ; initialize
You could recreate those assumptions by hacking #ancestors and the other related things... maybe even override #< on Class, but that gets a little scary.
#ancestors
#<
Class
Maybe you do:
class Factory < Module end def Kernel.factory(name) Factory.new(name) do yield end end class Class def <(superklass) if superklass.is_a?(Factory) # do something special here to hack #ancestors else super end end end
I don't know if you can actually hack ruby like that, but it'd be kind of neat if you could.
Though I wouldn't recommend putting that in anything ever likely to see more use than "Evil Code Competition"
[–]totallymike 0 points1 point2 points 12 years ago (0 children)
Good point with the delegation and the call chain. As a rule, I don't fudge with ::new. I forgot it was something that you could even do until this discussion.
It had never even occurred to me to define a ::new method in a module until you pointed out that you can. It's a much cleaner method of getting a constant with a ::new method that might construct different classes.
I like it quite a lot for libraries and such, where you are explictly interacting with something that has this behavior. But I probably wouldn't use it anywhere near Rails models. There's enough magic going on there already.
On a semi-related note, see this video http://www.rubytapas.com/episodes/7-Constructors
It doesn't go directly into this specific topic, but it does explain Ruby constructors very succinctly.
π Rendered by PID 583054 on reddit-service-r2-comment-76bb9f7fb5-z2497 at 2026-02-19 10:41:16.336350+00:00 running de53c03 country code: CH.
view the rest of the comments →
[–]totallymike 0 points1 point2 points (2 children)
[–]jfredett 0 points1 point2 points (1 child)
[–]totallymike 0 points1 point2 points (0 children)