Hi, I''m having trouble to factor some simple code. Since, I have been stuck for several days now I ask the question here. # Beginning of code module DefWithName def integer(name, options = {}) store_result name, MyInteger.new(options) end def id(name) integer(name, an_options: true) end end module DefWithoutName def integer(options = {}) store_result MyInteger.new(options) end def id integer(an_options: true) end end class A; include DefWithName; end class AA; include DefWithName; end class B; include DefWithoutName; end class BB; include DefWithoutName; end # End of code Constraints: - The "id" function has to call "integer" and not "store_result" because it may be defined as a plugin. - The functions must still raise ArgumentError as they already do. Any ideas? Regards, -Nico -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/groups/opt_out.
On Monday, March 4, 2013 12:59:23 PM UTC, Nicolas Desprès wrote:> Hi, > > > Constraints: > - The "id" function has to call "integer" and not "store_result" because it may be defined as a plugin. > - The functions must still raise ArgumentError as they already do. > >Could you give some examples of what you''re trying to do or problems you''ve run into? You''ve posted some code but haven''t described how you''ll be using it and in what way it isn''t adequate.In fewer words: I don''t see what your question is. Fred -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/DbORKjnIelcJ. For more options, visit https://groups.google.com/groups/opt_out.
On Mon, Mar 4, 2013 at 7:36 PM, Frederick Cheung <frederick.cheung-Re5JQEeQqe8@public.gmane.orgm> wrote:> On Monday, March 4, 2013 12:59:23 PM UTC, Nicolas Desprès wrote: > > Hi, > > > > > > Constraints: > > - The "id" function has to call "integer" and not "store_result" because > it may be defined as a plugin. > > - The functions must still raise ArgumentError as they already do. > > > > > > Could you give some examples of what you''re trying to do or problems > you''ve run into? You''ve posted some code but haven''t described how you''ll > be using it and in what way it isn''t adequate.In fewer words: I don''t see > what your question is. >Thanks for replying. Yes sorry. I realize that some context is missing. # I am writing an API where the users are allowed to write something like that: FooContextWithName.new.eval do |o| o.integer "id", an_option: true # [1] o.integer "foo", an_option: true # [2] o.bar "a_name" do |o| o.integer an_option: true # [3] end end # I would like that users are able to factor [1] and [2] by writing a small plugin like this: module MyHelpers def id(name = "id") integer name, an_option: true end end MyLib.add_helpers(MyHelpers) # add_helpers would be defined appropriately # To factor [3] users should be able to write something like that: module MyHelpers def id integer an_option: true end end # To implement this API I have something like this module DefWithName def integer(name, options = {}) store_result name, MyInteger.new(options) end end module DefWithoutName def integer(options = {}) store_result MyInteger.new(options) end end class FooWithName < BasicObject include DefWithName def store_result(name, object) @props[name] = object end end class BarWithoutName < BasicObject include DefWithoutName def store_result(object) @items << object end end ==========================My goal is to provide a way for users to write their "id" method once and to work in both cases. I am thinking about something like that: def id(*args) if name_required? name = name_given? ? given_name : "id" end integer name, an_option: true end def integer(*args) value = MyInteger.new(options) if name_required? if name_given? store_result given_name, value else raise ArgumentError end else if name_given? raise ArgumentError end store_result value end end where "name_required?", "given_name" and "name_given?" would be defined appropriately based on the arguments passed to the method. I hope this is clearer now. -- Nicolas Desprès -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/groups/opt_out.
On Tue, Mar 5, 2013 at 10:37 AM, Nicolas Desprès <nicolas.despres-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> > > On Mon, Mar 4, 2013 at 7:36 PM, Frederick Cheung < > frederick.cheung-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> On Monday, March 4, 2013 12:59:23 PM UTC, Nicolas Desprès wrote: >> > Hi, >> > >> > >> > Constraints: >> > - The "id" function has to call "integer" and not "store_result" >> because it may be defined as a plugin. >> > - The functions must still raise ArgumentError as they already do. >> > >> > >> >> Could you give some examples of what you''re trying to do or problems >> you''ve run into? You''ve posted some code but haven''t described how you''ll >> be using it and in what way it isn''t adequate.In fewer words: I don''t see >> what your question is. >> > > Thanks for replying. > > Yes sorry. I realize that some context is missing. > > # I am writing an API where the users are allowed to write something like > that: > > FooContextWithName.new.eval do |o| > o.integer "id", an_option: true # [1] > o.integer "foo", an_option: true # [2] > o.bar "a_name" do |o| > o.integer an_option: true # [3] > end > end > > # I would like that users are able to factor [1] and [2] by writing a > small plugin like this: > > module MyHelpers > def id(name = "id") > integer name, an_option: true > end > end > MyLib.add_helpers(MyHelpers) # add_helpers would be defined appropriately > > # To factor [3] users should be able to write something like that: > > module MyHelpers > def id > integer an_option: true > end > end > > # To implement this API I have something like this > > module DefWithName > def integer(name, options = {}) > store_result name, MyInteger.new(options) > end > end > > module DefWithoutName > def integer(options = {}) > store_result MyInteger.new(options) > end > end > > class FooWithName < BasicObject > include DefWithName > > def store_result(name, object) > @props[name] = object > end > end > > class BarWithoutName < BasicObject > include DefWithoutName > > def store_result(object) > @items << object > end > end > > ==========================> My goal is to provide a way for users to write their "id" method once and > to work in both cases. > > I am thinking about something like that: > > def id(*args) > if name_required? > name = name_given? ? given_name : "id" > end > > integer name, an_option: true > end > > def integer(*args) > value = MyInteger.new(options) > if name_required? > if name_given? > store_result given_name, value > else > raise ArgumentError > end > else > if name_given? > raise ArgumentError > end > store_result value > end > end > > where "name_required?", "given_name" and "name_given?" would be defined > appropriately based on the arguments passed to the method. > > I hope this is clearer now. > >I finally found a good way to factor this. Instead of having two modules DefWithoutName and DefWithName I have only one: module BasicDef def integer(name, options = {}) store_result name, MyInteger.new(options) end end Then I use a proxy for evaluation that will - in the case of "with name" will call directly the target method and pass it all the arguments - in the case of "without name" will call the target method by passing "nil" as first arguments and then the rest of the arguments. The proxy checks when the target method requires a name as first argument using the Method#parameters method. -- Nicolas Desprès -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit https://groups.google.com/groups/opt_out.