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.