Skip to content

Instantly share code, notes, and snippets.

@wycats
Created June 11, 2010 18:16
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save wycats/434844 to your computer and use it in GitHub Desktop.
Save wycats/434844 to your computer and use it in GitHub Desktop.

If one was inclined to use the acts_as_yaffle pattern, they would probably use the second one, rather than the heavily cargo-culted first one.

module Yaffle
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field
self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s
send :include, InstanceMethods
end
end
module InstanceMethods
def squawk(string)
write_attribute(self.class.yaffle_text_field, string.to_squawk)
end
end
end
ActiveRecord::Base.send :include, Yaffle
module Yaffle
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field
self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s
include InstanceMethods
end
module InstanceMethods
def squawk(string)
write_attribute(self.class.yaffle_text_field, string.to_squawk)
end
end
end
ActiveRecord::Base.extend(Yaffle)
module Yaffle
# since this is for internal consumption only, just extend directly;
# don't rewrite the include method to mean extend
def self.included(base)
# extend is a public method
base.send :extend, ClassMethods
end
# if we extended directly, we could get rid of the ClassMethods
# module and move the methods into the Yaffle module. You onluy
# ever need one of ClassMethods or InstanceMethods
module ClassMethods
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field
self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s
# we're inside the class, so we don't need to use send to
# use a private method
send :include, InstanceMethods
end
end
module InstanceMethods
def squawk(string)
write_attribute(self.class.yaffle_text_field, string.to_squawk)
end
end
end
# If we'd used extend, we wouldn't need a send
ActiveRecord::Base.send :include, Yaffle
@raggi
Copy link

raggi commented Jun 14, 2010

with my last code, all you do is:

include Yaffle
self.yaffle_text_field = "blah"

If cattr_accessor was changed to allow for sets by parameter on the reader method, then this would read even better:

include Yaffle
yaffle_text_field "blah"

And can be implemented easily.

You seem to be unaware that:

class A; include B, C, D; end

is valid right now.

@twifkak
Copy link

twifkak commented Jun 14, 2010

Actually, your last code will raise a "NoMethodError: undefined method options". I get what you're saying, but in general, whatever initialization included() does might not be easily reversible.

I was unaware that Module#include took *args. Oh, well! I suppose one could check the type of the second arg, since I doubt anybody depends on include raising a TypeError.

@raggi
Copy link

raggi commented Jun 14, 2010

meh. two lines of code for users is fine. breaking stuff for the sake of replacing "\n" with ", :([^ ]+) => " is silly IMO

@raggi
Copy link

raggi commented Jun 14, 2010

anyone know how to /ignore further comments on a gist?

@twifkak
Copy link

twifkak commented Jun 15, 2010

Wow. It doesn't take a genius to realize that there are many places to ask that question that are more likely to garner an answer than in the comments of a gist that six people have posted to. You did that just to broadcast that you disagreed with and disapproved of me. Presumably, you thought that doing so would either shame me or inform others of your superiority. To me, it communicated your inability to handle dissent.

I read the anguish in your earlier comments as intolerance of whimsy. I take it you'll be celebrating whyday for a reason entirely different from most.

@raggi
Copy link

raggi commented Jun 15, 2010

i was only asking because i'm done with this.

oh, i see, you were trying to be "artistic"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment