Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Help me understand this technique from an open source app?
Pito Salas
1/24/2009 2:08:00 PM
n the code at the bottom (from HTTParty), the module is included in
some other class ("O"), and among the effects is that (for example)
the method default_params becomes available in "O". I don't understand
the technique. Given that the module is used as a mixin, then if I
wanted to have that method, I could just define it under module
HTTParty with a normal def. Moreover, the following doesn't work:
class Parent
include HTTParty
def my_method
default_params :x => "X"
end
end
class Child < Parent
def other
my_method
end
end
There's some sophisticated meta programming going on. Any help
understanding it would be greatly appreciated!
Pito
=============from HTTParty==============
module HTTParty
AllowedFormats = {:xml => 'text/xml', :json => 'application/json',
:html => 'text/html'}
def self.included(base)
base.extend ClassMethods
base.send :include, ModuleLevelInheritableAttributes
base.send(:mattr_inheritable, :default_options)
base.instance_variable_set("@default_options", {})
end
module ClassMethods
def default_options
@default_options
end
def http_proxy(addr=nil, port = nil)
default_options[:http_proxyaddr] = addr
default_options[:http_proxyport] = port
end
def base_uri(uri=nil)
return default_options[:base_uri] unless uri
default_options[:base_uri] = HTTParty.normalize_base_uri(uri)
end
def basic_auth(u, p)
default_options[:basic_auth] = {:username => u, :password => p}
end
def default_params(h={})
raise ArgumentError, 'Default params must be a hash' unless
h.is_a?(Hash)
default_options[:default_params] ||= {}
default_options[:default_params].merge!(h)
end
def headers(h={})
raise ArgumentError, 'Headers must be a hash' unless h.is_a?
(Hash)
default_options[:headers] ||= {}
default_options[:headers].merge!(h)
end
def format(f)
raise UnsupportedFormat, "Must be one of:
#{AllowedFormats.keys.join(', ')}" unless AllowedFormats.key?(f)
default_options[:format] = f
end
def get(path, options={})
perform_request Net::HTTP::Get, path, options
end
def post(path, options={})
perform_request Net::HTTP::Post, path, options
end
def put(path, options={})
perform_request Net::HTTP::Put, path, options
end
def delete(path, options={})
perform_request Net::HTTP::Delete, path, options
end
private
def perform_request(http_method, path, options) #:nodoc:
Request.new(http_method, path,
default_options.dup.merge(options)).perform
end
end
--
Posted via
http://www.ruby-...
.
1 Answer
Brian Candler
1/25/2009 3:41:00 PM
0
Pito Salas wrote:
> n the code at the bottom (from HTTParty), the module is included in
> some other class ("O"), and among the effects is that (for example)
> the method default_params becomes available in "O".
Well, consider this first:
module ClassMethods
def foo
puts "hello from class"
end
end
module InstanceMethods
def bar
puts "hello from instance"
end
end
class Parent
include InstanceMethods
extend ClassMethods
end
Parent.foo
Parent.new.bar
However this pattern is very common, so it's refactored in two ways.
1. put the module containing class methods *inside* the module
containing the instance methods
module MyTools
... instance methods go here
module ClassMethods
... class methods go here
end
end
2. use the "included" hook so that when you include MyTools, it
automatically does extend MyTools::ClassMethods at the same time.
The example above becomes:
module MyTools
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def foo
puts "hello from class"
end
end
def bar
puts "hello from instance"
end
end
class Parent
include MyTools
end
Parent.foo
Parent.new.bar
At least, I *think* that's what you were asking about. There's also the
ModuleLevelInheritableAttributes there, but you didn't post all the code
for that. But notice that the include hook is calling
mattr_inheritable :default_options
in the base class, and also setting a class instance variable.
HTH,
Brian.
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Help me understand this technique from an open source app?
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password