|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
[Note: parts of this message were removed to make it a legal post.]
I Can't seem to find any documentation or explanation as to why paramix has been forcibly deprecated from facets: http://facets.rubyforge.org/doc/changes.html And apparently that lack of documentation means not too many other people were making use of this cool tool. You see a similar technique used a lot in rails. For example, you'll add the make_resourceful plugin and now all of your controller have the class method make_resourceful. (And that takes some arguments) And when you call it ends up including some module from the plugin that adds things to your controller. great. But all of that takes a fair amount of up-front class_eval to add the make_resourceful class method to everything. For simple add-ons I like to use paramix. For example, I have a simple module called SqlSearch, and I do include SqlSearch, n => ['name', 'content']paramix gives me access to those hash parameters in my self.included(base) call in the module. So much simpler and cleaner than declaring class method everywhere, and there's a clear and definite association here. You KNOW to look for a SqlSearch module to find out what's going on I could instead have defined the sql_search class method on ActiveRecord::Base... but then I have to have require 'sql_search', I can't just have the const_missing SqlSearch trigger the load needed.... messiness? Anybody get what I'm talking about? Why get rid of such a useful thing? What's a good alternative? I debate making my own such thing, something like: include_mod SqlSearch, n => ['name', 'content']and then the callback is self.mod_included(base)... feels hackity Any thoughts? Jacob |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Mar 31, 6:27 pm, "Jacob Burkhart" <igoti...@gmail.com> wrote: > I Can't seem to find any documentation or explanation as to why paramix has > been forcibly deprecated from facets:http://facets.rubyforge.org/doc/changes.html > > And apparently that lack of documentation means not too many other people > were making use of this cool tool. > > You see a similar technique used a lot in rails. For example, you'll add > the make_resourceful plugin and now all of your controller have the class > method make_resourceful. (And that takes some arguments) And when you call > it ends up including some module from the plugin that adds things to your > controller. great. > > But all of that takes a fair amount of up-front class_eval to add the > make_resourceful class method to everything. > > For simple add-ons I like to use paramix. > > For example, I have a simple module called SqlSearch, and I do > > include SqlSearch, n => ['name', 'content']> > paramix gives me access to those hash parameters in my self.included(base) > call in the module. So much simpler and cleaner than declaring class method > everywhere, and there's a clear and definite association here. You KNOW to > look for a SqlSearch module to find out what's going on I could instead > have defined the sql_search class method on ActiveRecord::Base... but then > I have to have require 'sql_search', I can't just have the const_missing > SqlSearch trigger the load needed.... messiness? > > Anybody get what I'm talking about? Why get rid of such a useful thing? > What's a good alternative? > > I debate making my own such thing, something like: > > include_mod SqlSearch, n => ['name', 'content']> > and then the callback is self.mod_included(base)... feels hackity > > Any thoughts? Hi Jacob, It was a bit premature of me to remove it. My apologies. I encountered some conflicts between it and other libs and had to reconsider it. The idea is great, no doubt. Unfortunately the implementation was invasive --it overrode #include and #extend. Considering it further I felt it would be better to deprecate it rather then continue to promote a non- robust lib; and I've already started on a new version. I'm hoping to manage a highly robust implementation with much the same interface, except using captialize methods rather than overriding #include. Eg. class X include PMix(:parm=>"foo") end I worked on it last night, but it's a tough nut. If you (or anyone else) is interested in implementing this please take a whack. Hopefully I can get it into next Facets release. (2.4.1 in a week or so). In the mean time I've include a copy of the old version below if you need a (copy and paste) fix asap. T. ---- Here's the old deprecated version of paramix.rb ---- # TITLE: # # Parametric Mixins # # SUMMARY: # # Parametric Mixins provides parameters for mixin modules. # # COPYRIGHT: # # Copyright (c) 2005 Thomas Sawyer, George Moschovitis # # LICENSE: # # Ruby License # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # # AUTHORS: # # - Thomas Sawyer # - George Moschovitis require 'facets/module/name' # for basename # = Parametric Mixins # # Parametric Mixins provides parameters for mixin modules. # Module parameters can be set at the time of inclusion or extension, # then accessed via an instance method of the same name as the included # module. # # == Synopsis # # module Mixin # def hello # puts "Hello from #{Mixin(:name)}" # end # end # # class MyClass # include Mixin, :name => 'Ruby' # end # # m = MyClass.new # m.hello -> 'Hello from Ruby' # # You can view the full set of parameters via the #mixin_parameters # class method, which returns a hash keyed on the included modules. # # MyClass.mixin_parameters #=> {Mixin=>{:name=>'Ruby'}} # MyClass.mixin_parameters[Mixin] #=> {:name=>'Ruby'} # # To create _dynamic mixins_ you can use the #included callback # method along with mixin_parameters method like so: # # module Mixin # def self.included( base ) # parms = base.mixin_parameters[self] # base.class_eval { # def hello # puts "Hello from #{parms(:name)}" # end # } # end # end # # More conveniently a new callback has been added, #included_with_parameters, # which passes in the parameters in addition to the base class/module. # # module Mixin # def self.included_with_parameters( base, parms ) # base.class_eval { # def hello # puts "Hello from #{parms(:name)}" # end # } # end # end # # We would prefer to have passed the parameters through the #included callback # method itself, but implementation of such a feature is much more complicated. # If a reasonable solution presents itself in the future however, we will fix. class Module # Store for module parameters. This is local per module # and indexed on module/class included-into. def mixin_parameters ; @mixin_parameters ||= {} ; end alias_method :include_without_parameters, :include def include(*args) params = args.last.is_a?(Hash) ? args.pop : {} args.each do |mod| mixin_parameters[mod] = params if mod.basename define_method( mod.basename ) do |key| if params.key?(key) params[key] else super if defined?( super ) end end end end r = include_without_parameters(*args) for mod in args if mod.respond_to?(:included_with_parameters) mod.included_with_parameters( self, params ) end end r end alias_method :extend_without_parameters, :extend def extend(*args) params = args.last.is_a?(Hash) ? args.pop : {} args.each do |mod| (class << self; self; end).class_eval do mixin_parameters[mod] = params if mod.basename define_method( mod.basename ) do |key| if params.key?(key) params[key] else super if defined?( super ) end end end end end r = extend_without_parameters(*args) for mod in args if mod.method_defined?(:extended_with_parameters) mod.extended_with_parameters( self, params ) end end r end end |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Mar 31, 7:34 pm, Trans <transf...@gmail.com> wrote: > I worked on it last night, but it's a tough nut. Huh... it may have just a fallen into place. What do you think of: require 'facets/module/basename' require 'facets/module/modspace' module Paramix # or PatrametricMixin ? def self.append_features(base) base.modspace.module_eval %{ def #{base.basename.to_s}(parameters, &block) Delegator.new(#{base}, parameters, &block) end } end # It you want to define the module method by hand. You # can use Parmix.new instead of Parmix: elegator.new.def self.new(delegate_module, parameters={}, &base_block) Delegator.new(delegate_module, parameters, &base_block) end # class Delegator < Module attr :delegate_module attr :parameters attr :base_block def initialize(delegate_module, parameters={}, &base_block) @delegate_module = delegate_module @parameters = parameters @base_block = base_block end def append_features(base) base.__send__(:include, delegate_module) base.parametric_options[delegate_module] = parameters base.module_eval do define_method(:parametric_options) do base.parametric_options end end base.module_eval(&@base_block) if base_block end def [](name) @parameters[name] end end end class Module # Store for parametric mixin parameters. # # Returns a hash, the keys of which are the parametric mixin module # and the values are the parameters associacted with this module/ class. # # class C # include P(:x=>1) # end # # C.parametric_options[P] #=> {:x=>1} # def parametric_options @parametric_options ||= {} end end # Try it out if __FILE__ == $0 module O include Paramix def x parametric_options[O][:x] end end # If doing it by hand instead of using include Paramix. #def O(options) # Paramix.new(O, options) #end class X include O(:x=>1) end x = X.new p x.x p X.ancestors end T. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Mar 31, 2008, at 4:27 PM, Jacob Burkhart wrote: > But all of that takes a fair amount of up-front class_eval to add the > make_resourceful class method to everything. ?? module SqlSearch def SqlSearch.bless other, options = {} stuff_with options other.send :include, self end end class Module def sqlsearch options = {} SqlSearch.bless self, options end end a @ http://codeforpeople.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
[Note: parts of this message were removed to make it a legal post.]
Hey Tran, Thanks for re-adding Paramix to facets! I seem to be getting a conflict with another thing called Delegator in class_eval. So this seems to work better: def self.append_features(base) base.modspace.module_eval %{ def #{base.basename.to_s}(parameters, &block) Paramix: elegator.new(#{base}, parameters, &block)end } end and I also had to change the order of things in append_features so that the include is last, because I want to be able to reference mixin_parameters in self.included: def append_features(base) base.mixin_parameters[delegate_module] = parameters base.module_eval do define_method(:mixin_parameters) do base.mixin_parameters end end base.__send__(:include, delegate_module) base.module_eval(&@base_block) if base_block end Can we get these changes in the next version of facets? thanks, Jacob On Mon, Mar 31, 2008 at 9:25 PM, ara.t.howard <ara.t.howard@gmail.com> wrote: > > On Mar 31, 2008, at 4:27 PM, Jacob Burkhart wrote: > > > But all of that takes a fair amount of up-front class_eval to add the > > make_resourceful class method to everything. > > > > ?? > > module SqlSearch > > def SqlSearch.bless other, options = {} > stuff_with options > other.send :include, self > end > > end > > class Module > def sqlsearch options = {} > SqlSearch.bless self, options > end > end > > a @ http://codeforpeople.com/ > -- > we can deny everything, except that we have the possibility of being > better. simply reflect on that. > h.h. the 14th dalai lama > > > > > |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Apr 7, 2:50 pm, "Jacob Burkhart" <igoti...@gmail.com> wrote: > Hey Tran, > > Thanks for re-adding Paramix to facets! > I seem to be getting a conflict with another thing called Delegator in > class_eval. > > So this seems to work better: > > def self.append_features(base) > base.modspace.module_eval %{ > def #{base.basename.to_s}(parameters, &block) > Paramix: elegator.new(#{base}, parameters, &block)> end > } > end Ah, good catch, I will fix. > and I also had to change the order of things in append_features so that the > include is last, because I want to be able to reference mixin_parameters in > self.included: > > def append_features(base) > base.mixin_parameters[delegate_module] = parameters > > base.module_eval do > define_method(:mixin_parameters) do > base.mixin_parameters > end > end > > base.__send__(:include, delegate_module) > > base.module_eval(&@base_block) if base_block > end Yep. I ran into that too and have already made that change. > Can we get these changes in the next version of facets? Yep. And I will be releasing 2.4.2 in a matter of days. Thanks Jacob, T. |
|
![]() |
| Outils de la discussion | |
|
|