printercu@gmail.com
2013-Apr-19 09:19 UTC
easy way to define pairs of setter and getter with blocks support
Hi there! I was looking for some stuff that works like layout declaration in controllers: class SomeController < ActionController::Base layout ''string'' layout :method layout -> { ''from proc'' } end What do you think about this: require ''active_support/core_ext/array'' class Module protected def define_pair(setter, *args) # getter = setter, options = {} options = args.extract_options! getter = args[0] || setter setter_visibility = options[:setter_visibility] || :protected getter_visibility = options[:getter_visibility] || :protected define_method getter do; end module_eval <<-RUBY, __FILE__, __LINE__ + 1 def self.#{setter}(*args, &block) # def self.layout(*args, &block) define_getter :#{getter}, :#{getter_visibility}, *args, &block # define_getter :_layout, :protected, *args, &block end # end # #{setter_visibility} :#{setter} # protected :layout #{getter_visibility} :#{getter} # protected :_layout RUBY end def define_getter(name, visibility, *args, &block) arg = block_given? ? block : args[0] method_body = case arg when Proc helper_method = "_#{name}_from_proc" define_method helper_method, &arg module_eval "#{visibility} :#{helper_method}" helper_method when Symbol arg else arg.inspect end module_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{name} # def _layout #{method_body} # # dependent stuff end # end #{visibility} :#{name} # protected :_layout RUBY end end # examples module Test define_pair :smth smth do "from proc rand: #{Random.rand(1000)}" end def result smth end end class A include Test end class B define_pair :other_one other_one :method def method :from_method end def result other_one end end class C < B end class D < B other_one ''string'' end puts "A: #{A.new.result}" # A: from proc rand: 78 puts "A#2: #{A.new.result}" #A#2: from proc rand: 380 puts "B: #{B.new.result}" #B: from_method puts "C: #{C.new.result}" #C: from_method puts "D: #{D.new.result}" #D: string It also can be replaced with method definitions, but one have to track methods visibility while redefining methods. And it''s also looks little prettier than method definition. Here is temporary method names think we need decide new ones if you like the stuff. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Nick Sutterer
2013-Apr-21 09:12 UTC
Re: easy way to define pairs of setter and getter with blocks support
Is that to provide blocks instead of methods in the controller? On Friday, April 19, 2013 7:19:05 PM UTC+10, prin...@gmail.com wrote:> > Hi there! > > I was looking for some stuff that works like layout declaration in > controllers: > > class SomeController < ActionController::Base > layout ''string'' > layout :method > layout -> { ''from proc'' } > end > > > What do you think about this: > > require ''active_support/core_ext/array'' > > class Module > protected > def define_pair(setter, *args) # getter = setter, options = {} > options = args.extract_options! > getter = args[0] || setter > setter_visibility = options[:setter_visibility] || :protected > getter_visibility = options[:getter_visibility] || :protected > define_method getter do; end > module_eval <<-RUBY, __FILE__, __LINE__ + 1 > def self.#{setter}(*args, &block) > # def self.layout(*args, &block) > define_getter :#{getter}, :#{getter_visibility}, *args, &block > # define_getter :_layout, :protected, *args, &block > end > # end > > # > #{setter_visibility} :#{setter} > # protected :layout > #{getter_visibility} :#{getter} > # protected :_layout > RUBY > end > > def define_getter(name, visibility, *args, &block) > arg = block_given? ? block : args[0] > method_body = case arg > when Proc > helper_method = "_#{name}_from_proc" > define_method helper_method, &arg > module_eval "#{visibility} :#{helper_method}" > helper_method > when Symbol > arg > else > arg.inspect > end > module_eval <<-RUBY, __FILE__, __LINE__ + 1 > def #{name} # def _layout > #{method_body} # # dependent stuff > end # end > #{visibility} :#{name} # protected :_layout > RUBY > end > end > > > # examples > module Test > define_pair :smth > > smth do > "from proc rand: #{Random.rand(1000)}" > end > > def result > smth > end > end > > class A > include Test > end > > class B > define_pair :other_one > > other_one :method > > def method > :from_method > end > > def result > other_one > end > end > > class C < B > end > > class D < B > other_one ''string'' > end > > puts "A: #{A.new.result}" > > # A: from proc rand: 78 > > > > puts "A#2: #{A.new.result}" > > #A#2: from proc rand: 380 > > > > puts "B: #{B.new.result}" > > #B: from_method > > > > puts "C: #{C.new.result}" > > #C: from_method > > puts "D: #{D.new.result}" > > > > #D: string > > > It also can be replaced with method definitions, but one have to track > methods visibility while redefining methods. > And it''s also looks little prettier than method definition. > > Here is temporary method names think we need decide new ones if you like > the stuff. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
printercu@gmail.com
2013-Apr-22 04:53 UTC
Re: easy way to define pairs of setter and getter with blocks support
No, mostly for configuration purposes. It can be useful in cases when you need something like class_attribute but you need to run a block in getter in instance context. One can define method, but it would look less like metaprogramming. And also if method should be with specified visibility, it''s moved down to the right section, or one have to explicitly declare protected :method in every class where it''s defined. The most common example is ActiveController::Base::layout method. воскресенье, 21 апреля 2013 г., 13:12:28 UTC+4 пользователь Nick Sutterer написал:> > Is that to provide blocks instead of methods in the controller? > > On Friday, April 19, 2013 7:19:05 PM UTC+10, prin...@gmail.com wrote: >> >> Hi there! >> >> I was looking for some stuff that works like layout declaration in >> controllers: >> >> class SomeController < ActionController::Base >> layout ''string'' >> layout :method >> layout -> { ''from proc'' } >> end >> >> >> What do you think about this: >> >> require ''active_support/core_ext/array'' >> >> class Module >> protected >> def define_pair(setter, *args) # getter = setter, options = {} >> options = args.extract_options! >> getter = args[0] || setter >> setter_visibility = options[:setter_visibility] || :protected >> getter_visibility = options[:getter_visibility] || :protected >> define_method getter do; end >> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >> def self.#{setter}(*args, &block) >> # def self.layout(*args, &block) >> define_getter :#{getter}, :#{getter_visibility}, *args, &block >> # define_getter :_layout, :protected, *args, &block >> end >> # end >> >> # >> #{setter_visibility} :#{setter} >> # protected :layout >> #{getter_visibility} :#{getter} >> # protected :_layout >> RUBY >> end >> >> def define_getter(name, visibility, *args, &block) >> arg = block_given? ? block : args[0] >> method_body = case arg >> when Proc >> helper_method = "_#{name}_from_proc" >> define_method helper_method, &arg >> module_eval "#{visibility} :#{helper_method}" >> helper_method >> when Symbol >> arg >> else >> arg.inspect >> end >> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >> def #{name} # def _layout >> #{method_body} # # dependent stuff >> end # end >> #{visibility} :#{name} # protected :_layout >> RUBY >> end >> end >> >> >> # examples >> module Test >> define_pair :smth >> >> smth do >> "from proc rand: #{Random.rand(1000)}" >> end >> >> def result >> smth >> end >> end >> >> class A >> include Test >> end >> >> class B >> define_pair :other_one >> >> other_one :method >> >> def method >> :from_method >> end >> >> def result >> other_one >> end >> end >> >> class C < B >> end >> >> class D < B >> other_one ''string'' >> end >> >> puts "A: #{A.new.result}" >> >> # A: from proc rand: 78 >> >> >> >> puts "A#2: #{A.new.result}" >> >> #A#2: from proc rand: 380 >> >> >> >> puts "B: #{B.new.result}" >> >> #B: from_method >> >> >> >> puts "C: #{C.new.result}" >> >> #C: from_method >> >> puts "D: #{D.new.result}" >> >> >> >> #D: string >> >> >> It also can be replaced with method definitions, but one have to track >> methods visibility while redefining methods. >> And it''s also looks little prettier than method definition. >> >> Here is temporary method names think we need decide new ones if you like >> the stuff. >> >>-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Nick Sutterer
2013-Apr-23 04:01 UTC
Re: easy way to define pairs of setter and getter with blocks support
That''s what I''m asking, something like class UserController < .. layout do run_this_in_instance_ctx end ??? On Monday, April 22, 2013 2:53:01 PM UTC+10, prin...@gmail.com wrote:> > No, mostly for configuration purposes. > > It can be useful in cases when you need something like class_attributebut you need to run a block in getter in instance context. > One can define method, but it would look less like metaprogramming. And > also if method should be with specified visibility, it''s moved down to the > right section, or one have to explicitly declare protected :method in > every class where it''s defined. > > The most common example is ActiveController::Base::layout method. > > воскресенье, 21 апреля 2013 г., 13:12:28 UTC+4 пользователь Nick Sutterer > написал: >> >> Is that to provide blocks instead of methods in the controller? >> >> On Friday, April 19, 2013 7:19:05 PM UTC+10, prin...@gmail.com wrote: >>> >>> Hi there! >>> >>> I was looking for some stuff that works like layout declaration in >>> controllers: >>> >>> class SomeController < ActionController::Base >>> layout ''string'' >>> layout :method >>> layout -> { ''from proc'' } >>> end >>> >>> >>> What do you think about this: >>> >>> require ''active_support/core_ext/array'' >>> >>> class Module >>> protected >>> def define_pair(setter, *args) # getter = setter, options = {} >>> options = args.extract_options! >>> getter = args[0] || setter >>> setter_visibility = options[:setter_visibility] || :protected >>> getter_visibility = options[:getter_visibility] || :protected >>> define_method getter do; end >>> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >>> def self.#{setter}(*args, &block) >>> # def self.layout(*args, &block) >>> define_getter :#{getter}, :#{getter_visibility}, *args, &block >>> # define_getter :_layout, :protected, *args, &block >>> end >>> # end >>> >>> # >>> #{setter_visibility} :#{setter} >>> # protected :layout >>> #{getter_visibility} :#{getter} >>> # protected :_layout >>> RUBY >>> end >>> >>> def define_getter(name, visibility, *args, &block) >>> arg = block_given? ? block : args[0] >>> method_body = case arg >>> when Proc >>> helper_method = "_#{name}_from_proc" >>> define_method helper_method, &arg >>> module_eval "#{visibility} :#{helper_method}" >>> helper_method >>> when Symbol >>> arg >>> else >>> arg.inspect >>> end >>> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >>> def #{name} # def _layout >>> #{method_body} # # dependent stuff >>> end # end >>> #{visibility} :#{name} # protected :_layout >>> RUBY >>> end >>> end >>> >>> >>> # examples >>> module Test >>> define_pair :smth >>> >>> smth do >>> "from proc rand: #{Random.rand(1000)}" >>> end >>> >>> def result >>> smth >>> end >>> end >>> >>> class A >>> include Test >>> end >>> >>> class B >>> define_pair :other_one >>> >>> other_one :method >>> >>> def method >>> :from_method >>> end >>> >>> def result >>> other_one >>> end >>> end >>> >>> class C < B >>> end >>> >>> class D < B >>> other_one ''string'' >>> end >>> >>> puts "A: #{A.new.result}" >>> >>> # A: from proc rand: 78 >>> >>> >>> >>> puts "A#2: #{A.new.result}" >>> >>> #A#2: from proc rand: 380 >>> >>> >>> >>> puts "B: #{B.new.result}" >>> >>> #B: from_method >>> >>> >>> >>> puts "C: #{C.new.result}" >>> >>> #C: from_method >>> >>> puts "D: #{D.new.result}" >>> >>> >>> >>> #D: string >>> >>> >>> It also can be replaced with method definitions, but one have to track >>> methods visibility while redefining methods. >>> And it''s also looks little prettier than method definition. >>> >>> Here is temporary method names think we need decide new ones if you like >>> the stuff. >>> >>>-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
printercu@gmail.com
2013-Apr-23 04:56 UTC
Re: easy way to define pairs of setter and getter with blocks support
yeah, but not only controllers - any class вторник, 23 апреля 2013 г., 8:01:36 UTC+4 пользователь Nick Sutterer написал:> > That''s what I''m asking, something like > > class UserController < .. > layout do > run_this_in_instance_ctx > end > > ??? > > On Monday, April 22, 2013 2:53:01 PM UTC+10, prin...@gmail.com wrote: >> >> No, mostly for configuration purposes. >> >> It can be useful in cases when you need something like class_attributebut you need to run a block in getter in instance context. >> One can define method, but it would look less like metaprogramming. And >> also if method should be with specified visibility, it''s moved down to the >> right section, or one have to explicitly declare protected :method in >> every class where it''s defined. >> >> The most common example is ActiveController::Base::layout method. >> >> воскресенье, 21 апреля 2013 г., 13:12:28 UTC+4 пользователь Nick Sutterer >> написал: >>> >>> Is that to provide blocks instead of methods in the controller? >>> >>> On Friday, April 19, 2013 7:19:05 PM UTC+10, prin...@gmail.com wrote: >>>> >>>> Hi there! >>>> >>>> I was looking for some stuff that works like layout declaration in >>>> controllers: >>>> >>>> class SomeController < ActionController::Base >>>> layout ''string'' >>>> layout :method >>>> layout -> { ''from proc'' } >>>> end >>>> >>>> >>>> What do you think about this: >>>> >>>> require ''active_support/core_ext/array'' >>>> >>>> class Module >>>> protected >>>> def define_pair(setter, *args) # getter = setter, options = {} >>>> options = args.extract_options! >>>> getter = args[0] || setter >>>> setter_visibility = options[:setter_visibility] || :protected >>>> getter_visibility = options[:getter_visibility] || :protected >>>> define_method getter do; end >>>> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >>>> def self.#{setter}(*args, &block) >>>> # def self.layout(*args, &block) >>>> define_getter :#{getter}, :#{getter_visibility}, *args, >>>> &block # define_getter :_layout, :protected, *args, &block >>>> end >>>> # end >>>> >>>> # >>>> #{setter_visibility} :#{setter} >>>> # protected :layout >>>> #{getter_visibility} :#{getter} >>>> # protected :_layout >>>> RUBY >>>> end >>>> >>>> def define_getter(name, visibility, *args, &block) >>>> arg = block_given? ? block : args[0] >>>> method_body = case arg >>>> when Proc >>>> helper_method = "_#{name}_from_proc" >>>> define_method helper_method, &arg >>>> module_eval "#{visibility} :#{helper_method}" >>>> helper_method >>>> when Symbol >>>> arg >>>> else >>>> arg.inspect >>>> end >>>> module_eval <<-RUBY, __FILE__, __LINE__ + 1 >>>> def #{name} # def _layout >>>> #{method_body} # # dependent stuff >>>> end # end >>>> #{visibility} :#{name} # protected :_layout >>>> RUBY >>>> end >>>> end >>>> >>>> >>>> # examples >>>> module Test >>>> define_pair :smth >>>> >>>> smth do >>>> "from proc rand: #{Random.rand(1000)}" >>>> end >>>> >>>> def result >>>> smth >>>> end >>>> end >>>> >>>> class A >>>> include Test >>>> end >>>> >>>> class B >>>> define_pair :other_one >>>> >>>> other_one :method >>>> >>>> def method >>>> :from_method >>>> end >>>> >>>> def result >>>> other_one >>>> end >>>> end >>>> >>>> class C < B >>>> end >>>> >>>> class D < B >>>> other_one ''string'' >>>> end >>>> >>>> puts "A: #{A.new.result}" >>>> >>>> # A: from proc rand: 78 >>>> >>>> >>>> >>>> puts "A#2: #{A.new.result}" >>>> >>>> #A#2: from proc rand: 380 >>>> >>>> >>>> >>>> puts "B: #{B.new.result}" >>>> >>>> #B: from_method >>>> >>>> >>>> >>>> puts "C: #{C.new.result}" >>>> >>>> #C: from_method >>>> >>>> puts "D: #{D.new.result}" >>>> >>>> >>>> >>>> #D: string >>>> >>>> >>>> It also can be replaced with method definitions, but one have to track >>>> methods visibility while redefining methods. >>>> And it''s also looks little prettier than method definition. >>>> >>>> Here is temporary method names think we need decide new ones if you >>>> like the stuff. >>>> >>>>-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.