Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #2616 > unrolled thread
| Started by | Lars Olsson <lasso@lassoweb.se> |
|---|---|
| First post | 2011-04-11 02:19 -0700 |
| Last post | 2011-04-14 12:07 -0500 |
| Articles | 20 on this page of 23 — 4 participants |
Back to article view | Back to comp.lang.ruby
Copying parameters to singleton class Lars Olsson <lasso@lassoweb.se> - 2011-04-11 02:19 -0700
Re: Copying parameters to singleton class Robert Klemme <shortcutter@googlemail.com> - 2011-04-11 04:34 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-11 21:21 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-11 21:05 -0500
Re: Copying parameters to singleton class Robert Klemme <shortcutter@googlemail.com> - 2011-04-12 01:53 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 13:31 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 19:08 -0500
Re: Copying parameters to singleton class Jesús Gabriel y Galán <jgabrielygalan@gmail.com> - 2011-04-11 04:36 -0500
Re: Copying parameters to singleton class Lars Olsson <lasso@lassoweb.se> - 2011-04-11 02:53 -0700
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-11 21:48 -0500
Re: Copying parameters to singleton class Robert Klemme <shortcutter@googlemail.com> - 2011-04-12 02:00 -0500
Re: Copying parameters to singleton class Lars Olsson <lasso@lassoweb.se> - 2011-04-12 01:25 -0700
Re: Copying parameters to singleton class Robert Klemme <shortcutter@googlemail.com> - 2011-04-12 03:51 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 13:14 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 13:38 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 13:43 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-12 19:29 -0500
Re: Copying parameters to singleton class Lars Olsson <lasso@lassoweb.se> - 2011-04-13 01:49 -0700
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-13 19:32 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-13 19:49 -0500
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-13 20:09 -0500
Re: Copying parameters to singleton class Lars Olsson <lasso@lassoweb.se> - 2011-04-14 01:33 -0700
Re: Copying parameters to singleton class 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-14 12:07 -0500
Page 1 of 2 [1] 2 Next page →
| From | Lars Olsson <lasso@lassoweb.se> |
|---|---|
| Date | 2011-04-11 02:19 -0700 |
| Subject | Copying parameters to singleton class |
| Message-ID | <e7b941e2-199e-423b-97bb-7fee63905659@hg8g2000vbb.googlegroups.com> |
Hi list!
I have a metaprogramming question that is driving me mad. I though I
understood how to do it, but obviously I didn't. This is what I want
to do:
I want to create a class method that takes a bunch of options and
returns a singleton class with those options set,
class Opportunities
def self.using(options)
# Store options in singleton class variable @options and then
return singleton class
end
def self.options
return @options
end
end
So that I can use:
foo = Opportunities.using({:one => 1, :two: => 2, :three => 3})
bar = Opportunities.using({:four => 4, :five: => 5, :six => 6})
and then
foo.options => {:one => 1, :two: => 2, :three => 3}
bar.options => {:four => 4, :five: => 5, :six => 6}
Please note that I don't want instances of the Opportunities class, I
want two separate classes that shares the same behavior except for
that they return different values for the Opportunities.options call.
This really should be possible with ruby, right?
/lasso
[toc] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-11 04:34 -0500 |
| Message-ID | <BANLkTimh8S9MGSZ+GEteAM70Hs4-bUsDLg@mail.gmail.com> |
| In reply to | #2616 |
On Mon, Apr 11, 2011 at 11:20 AM, Lars Olsson <lasso@lassoweb.se> wrote:
> Hi list!
>
> I have a metaprogramming question that is driving me mad. I though I
> understood how to do it, but obviously I didn't. This is what I want
> to do:
>
> I want to create a class method that takes a bunch of options and
> returns a singleton class with those options set,
>
> class Opportunities
> def self.using(options)
> # Store options in singleton class variable @options and then
> return singleton class
> end
> def self.options
> return @options
> end
> end
>
> So that I can use:
>
> foo = Opportunities.using({:one => 1, :two: => 2, :three => 3})
> bar = Opportunities.using({:four => 4, :five: => 5, :six => 6})
>
> and then
>
> foo.options => {:one => 1, :two: => 2, :three => 3}
> bar.options => {:four => 4, :five: => 5, :six => 6}
>
> Please note that I don't want instances of the Opportunities class, I
> want two separate classes that shares the same behavior except for
> that they return different values for the Opportunities.options call.
>
> This really should be possible with ruby, right?
Right. You can use a closure like this:
class Opportunities
def self.using(opts)
opts.freeze
cl = Class.new self # so we can define instance methods
class<<cl;self;end.send(:define_method, :options) {opts}
cl
end
# inherited by all
def xyz
end
end
irb(main):019:0> foo = Opportunities.using(:one => 1, :two => 2, :three => 3)
=> #<Class:0x10958c78>
irb(main):020:0> bar = Opportunities.using(:four => 4, :five => 5, :six => 6)
=> #<Class:0x1095f7f8>
irb(main):021:0> foo.options
=> {:one=>1, :two=>2, :three=>3}
irb(main):022:0> bar.options
=> {:four=>4, :five=>5, :six=>6}
irb(main):023:0> f = foo.new
=> #<#<Class:0x10958c78>:0x109672dc>
irb(main):024:0> f.class.options
=> {:one=>1, :two=>2, :three=>3}
irb(main):025:0> f.class.ancestors
=> [#<Class:0x10958c78>, Opportunities, Object, Kernel, BasicObject]
Or you can use a member
class Opportunities
def self.using(opts)
cl = Class.new self
class<<cl
attr_reader :options
end
cl.instance_variable_set '@options', opts.freeze
cl
end
end
or this way
class Opportunities
class <<self
attr_reader :options
end
def self.using(opts)
cl = Class.new self
cl.instance_variable_set '@options', opts.freeze
cl
end
end
or this way
class Opportunities
class <<self
attr_reader :options
end
def self.using(opts)
Class.new(self).tap do |cl|
cl.instance_variable_set '@options', opts.freeze
end
end
end
Choose to your liking. :-)
Cheers
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-11 21:21 -0500 |
| Message-ID | <ad12dfe0935990a1f572bd427bf70576@ruby-forum.com> |
| In reply to | #2618 |
7stud -- wrote in post #992201: > Robert K. wrote in post #992088: >> >> Choose to your liking. :-) >> > > Hey Robert K, > > I read your factory pattern thread the other day, and I wonder if that > pattern would apply here? After all, producing several anonymous > instances of Class is akin to producing instances of various classes. In hindsight, I guess that wouldn't work if Opportunities is an existing class that needs to be reopened to provide the needed functionality. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-11 21:05 -0500 |
| Message-ID | <b3e6688a859aa5786908c1ee7a38c74c@ruby-forum.com> |
| In reply to | #2618 |
Robert K. wrote in post #992088:
>
> Choose to your liking. :-)
>
Hey Robert K,
I read your factory pattern thread the other day, and I wonder if that
pattern would apply here? After all, producing several anonymous
instances of Class is akin to producing instances of various classes.
Something like this:
class ClassFactory
def self.using(hash)
Class.new do
@options = hash
class << self
attr_reader :options
end
end
end
end
foo = Opportunities.using({one: 1, two: 2, three: 3})
bar = Opportunities.using({four: 4, five: 5, six: 6})
p foo.options
p bar.options
--output:--
{:one=>1, :two=>2, :three=>3}
{:four=>4, :five=>5, :six=>6}
Hey Lars Olsson,
Check out the shorter syntax for hashes when your keys are symbols.
foo = Opportunities.using({one: 1, two: 2, three: 3})
bar = Opportunities.using({four: 4, five: 5, six: 6})
p foo.options
p bar.options
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-12 01:53 -0500 |
| Message-ID | <BANLkTik1_94UE2n76GRzokpf6rO-OyEt_Q@mail.gmail.com> |
| In reply to | #2655 |
On Tue, Apr 12, 2011 at 4:05 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> Robert K. wrote in post #992088:
>>
>> Choose to your liking. :-)
>>
>
> Hey Robert K,
>
> I read your factory pattern thread the other day, and I wonder if that
> pattern would apply here? After all, producing several anonymous
> instances of Class is akin to producing instances of various classes.
> Something like this:
>
> class ClassFactory
> def self.using(hash)
> Class.new do
> @options = hash
>
> class << self
> attr_reader :options
> end
>
> end
> end
> end
Well, basically you just exchanged Opportunities with ClassFactory
compared to one of my examples. Actually method #using *is* a factory
method, no matter what class or instance it sits in.
> foo = Opportunities.using({one: 1, two: 2, three: 3})
> bar = Opportunities.using({four: 4, five: 5, six: 6})
I don't think this can work - at least there's something missing. Did
you mean to make Opportunities inherit ClassFactory? But IMHO there
is no point in splitting this up. Please note also that I made new
classes inherit Opportunities in order for inheritance to work.
> p foo.options
> p bar.options
>
> --output:--
> {:one=>1, :two=>2, :three=>3}
> {:four=>4, :five=>5, :six=>6}
>
>
> Hey Lars Olsson,
>
> Check out the shorter syntax for hashes when your keys are symbols.
>
> foo = Opportunities.using({one: 1, two: 2, three: 3})
> bar = Opportunities.using({four: 4, five: 5, six: 6})
If we start shortening it, we should do
foo = Opportunities.using(one: 1, two: 2, three: 3)
i.e. get rid of the superfluous pair of curly braces. :-)
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 13:31 -0500 |
| Message-ID | <004fd326b2c9744bcca068be0f7b87e5@ruby-forum.com> |
| In reply to | #2662 |
Robert K. wrote in post #992232: > On Tue, Apr 12, 2011 at 4:05 AM, 7stud -- <bbxx789_05ss@yahoo.com> > wrote: >> Something like this: >> end >> end >> end > > Well, basically you just exchanged Opportunities with ClassFactory > compared to one of my examples. Yes, that's true. > Did > you mean to make Opportunities inherit ClassFactory? Yes. I think you must have posted in the middle of one of my edits because Opportunities does inherit from ClassFactory. > But IMHO there > is no point in splitting this up. Please note also that I made new > classes inherit Opportunities in order for inheritance to work. > Yes, I noticed that, but I don't think that is a requirement. > If we start shortening it, we should do > > foo = Opportunities.using(one: 1, two: 2, three: 3) > > i.e. get rid of the superfluous pair of curly braces. :-) > Good catch. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 19:08 -0500 |
| Message-ID | <8007582e1dad8c8e61e3ed84c42529fd@ruby-forum.com> |
| In reply to | #2618 |
Robert K. wrote in post #992088:
>
> or this way
>
> class Opportunities
> class <<self
> attr_reader :options
> end
>
> def self.using(opts)
> Class.new(self).tap do |cl|
> cl.instance_variable_set '@options', opts.freeze
> end
> end
> end
>
>
The using() method in your last solution can be simplified:
def self.using(opts)
Class.new(self) do
@options = opts.freeze
end
end
And this bit in my last post:
singleton.singleton_class.class_eval do #<---SOLUTION***
def options
@options
end
end
is equivalent to:
singleton.instance_eval do
def options
@options
end
end
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Jesús Gabriel y Galán <jgabrielygalan@gmail.com> |
|---|---|
| Date | 2011-04-11 04:36 -0500 |
| Message-ID | <BANLkTimPCa=MeAmtF0X75P5wc9OoR6dsTg@mail.gmail.com> |
| In reply to | #2616 |
On Mon, Apr 11, 2011 at 11:20 AM, Lars Olsson <lasso@lassoweb.se> wrote:
> Hi list!
>
> I have a metaprogramming question that is driving me mad. I though I
> understood how to do it, but obviously I didn't. This is what I want
> to do:
>
> I want to create a class method that takes a bunch of options and
> returns a singleton class with those options set,
>
> class Opportunities
> def self.using(options)
> # Store options in singleton class variable @options and then
> return singleton class
> end
> def self.options
> return @options
> end
> end
>
> So that I can use:
>
> foo = Opportunities.using({:one => 1, :two: => 2, :three => 3})
> bar = Opportunities.using({:four => 4, :five: => 5, :six => 6})
>
> and then
>
> foo.options => {:one => 1, :two: => 2, :three => 3}
> bar.options => {:four => 4, :five: => 5, :six => 6}
>
> Please note that I don't want instances of the Opportunities class, I
> want two separate classes that shares the same behavior except for
> that they return different values for the Opportunities.options call.
If you don't want instances of Opportunities, of which class you want instances?
Where is the common behaviour of those objects defined?
> This really should be possible with ruby, right?
I'm not sure if I understand what you want, can you tell us why this
doesn't fit your requirements:
ruby-1.8.7-p334 :005 > class Opportunities
ruby-1.8.7-p334 :006?> attr_reader :options
ruby-1.8.7-p334 :007?> def initialize options
ruby-1.8.7-p334 :008?> @options = options
ruby-1.8.7-p334 :009?> end
ruby-1.8.7-p334 :010?> def self.using options
ruby-1.8.7-p334 :011?> new(options)
ruby-1.8.7-p334 :012?> end
ruby-1.8.7-p334 :013?> end
=> nil
ruby-1.8.7-p334 :014 > foo = Opportunities.using({:a => 3, :b => 4})
=> #<Opportunities:0xb7496418 @options={:b=>4, :a=>3}>
ruby-1.8.7-p334 :015 > foo.options
=> {:b=>4, :a=>3}
ruby-1.8.7-p334 :016 > bar = Opportunities.using({:a => 5, :b => 10})
=> #<Opportunities:0xb748e22c @options={:b=>10, :a=>5}>
ruby-1.8.7-p334 :017 > bar.options
=> {:b=>10, :a=>5}
Jesus.
[toc] | [prev] | [next] | [standalone]
| From | Lars Olsson <lasso@lassoweb.se> |
|---|---|
| Date | 2011-04-11 02:53 -0700 |
| Message-ID | <97b3ed20-63e1-4c85-bea6-2fb93409ad56@cu4g2000vbb.googlegroups.com> |
| In reply to | #2619 |
On 11 Apr, 11:36, Jesús Gabriel y Galán <jgabrielyga...@gmail.com>
wrote:
> On Mon, Apr 11, 2011 at 11:20 AM, Lars Olsson <la...@lassoweb.se> wrote:
> > Hi list!
>
> > I have a metaprogramming question that is driving me mad. I though I
> > understood how to do it, but obviously I didn't. This is what I want
> > to do:
>
> > I want to create a class method that takes a bunch of options and
> > returns a singleton class with those options set,
>
> > class Opportunities
> > def self.using(options)
> > # Store options in singleton class variable @options and then
> > return singleton class
> > end
> > def self.options
> > return @options
> > end
> > end
>
> > So that I can use:
>
> > foo = Opportunities.using({:one => 1, :two: => 2, :three => 3})
> > bar = Opportunities.using({:four => 4, :five: => 5, :six => 6})
>
> > and then
>
> > foo.options => {:one => 1, :two: => 2, :three => 3}
> > bar.options => {:four => 4, :five: => 5, :six => 6}
>
> > Please note that I don't want instances of the Opportunities class, I
> > want two separate classes that shares the same behavior except for
> > that they return different values for the Opportunities.options call.
>
> If you don't want instances of Opportunities, of which class you want instances?
> Where is the common behaviour of those objects defined?
>
> > This really should be possible with ruby, right?
>
> I'm not sure if I understand what you want, can you tell us why this
> doesn't fit your requirements:
>
> ruby-1.8.7-p334 :005 > class Opportunities
> ruby-1.8.7-p334 :006?> attr_reader :options
> ruby-1.8.7-p334 :007?> def initialize options
> ruby-1.8.7-p334 :008?> @options = options
> ruby-1.8.7-p334 :009?> end
> ruby-1.8.7-p334 :010?> def self.using options
> ruby-1.8.7-p334 :011?> new(options)
> ruby-1.8.7-p334 :012?> end
> ruby-1.8.7-p334 :013?> end
> => nil
> ruby-1.8.7-p334 :014 > foo = Opportunities.using({:a => 3, :b => 4})
> => #<Opportunities:0xb7496418 @options={:b=>4, :a=>3}>
> ruby-1.8.7-p334 :015 > foo.options
> => {:b=>4, :a=>3}
> ruby-1.8.7-p334 :016 > bar = Opportunities.using({:a => 5, :b => 10})
> => #<Opportunities:0xb748e22c @options={:b=>10, :a=>5}>
> ruby-1.8.7-p334 :017 > bar.options
> => {:b=>10, :a=>5}
>
> Jesus.
Actually, I don't want any instances at all. I would have preferred to
use instances myself, but since my task involves calling a framework
method that takes a class and not an "ordinary" instance I needed a
hack to be override the options method. Robert's solution does exactly
what I need.
Thank you for your speedy answers!
/lasso
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-11 21:48 -0500 |
| Message-ID | <50e4e16f7201aad2c97a193b4a2cfb82@ruby-forum.com> |
| In reply to | #2616 |
..but then you could do this:
module ClassFactory
def ClassFactory.included(includer)
includer.extend(ClassMethods)
end
module ClassMethods
def using(hash)
Class.new do
@options = hash
class << self
attr_reader :options
end
end
end
end
end
class Opportunities
include ClassFactory
end
Foo = Opportunities.using({one: 1, two: 2, three: 3})
Bar = Opportunities.using({four: 4, five: 5, six: 6})
p Foo.options
p Bar.options
--output:--
{:one=>1, :two=>2, :three=>3}
{:four=>4, :five=>5, :six=>6}
I really wanted to write that like below, but it doesn't work??
module ClassFactory
def ClassFactory.included(includer)
includer.extend(ClassMethods)
end
module ClassMethods
def using(hash)
Class.new do
@options = hash
end
end
def options
@options
end
end
end
class Opportunities
include ClassFactory
end
Foo = Opportunities.using({one: 1, two: 2, three: 3})
Bar = Opportunities.using({four: 4, five: 5, six: 6})
p Foo.options
p Bar.options
--output:--
prog.rb:28:in `<main>': undefined method `options' for Foo:Class
(NoMethodError)
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-12 02:00 -0500 |
| Message-ID | <BANLkTintiH8T4pwVHKdXKCK=VvMDfYp0bA@mail.gmail.com> |
| In reply to | #2656 |
On Tue, Apr 12, 2011 at 4:48 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> ...but then you could do this:
>
> module ClassFactory
> def ClassFactory.included(includer)
> includer.extend(ClassMethods)
> end
>
> module ClassMethods
>
> def using(hash)
> Class.new do
> @options = hash
> class << self
> attr_reader :options
> end
> end
> end
>
> end
> end
>
> class Opportunities
> include ClassFactory
> end
I think we can do this simpler if you want to reuse that options
creation functionality:
module ClassFactory
attr_reader :options
def using(opts)
Class.new(self).tap do |cl|
cl.instance_variable_set '@options', opts.freeze
end
end
end
class Opportunities
extend ClassFactory
end
irb(main):020:0> foo = Opportunities.using(foo: 1, bar: 2)
=> #<Class:0x10952bc0>
irb(main):021:0> foo.options
=> {:foo=>1, :bar=>2}
irb(main):022:0> foo.ancestors
=> [#<Class:0x10952bc0>, Opportunities, Object, Kernel, BasicObject]
> I really wanted to write that like below, but it doesn't work??
>
> module ClassFactory
> def ClassFactory.included(includer)
> includer.extend(ClassMethods)
> end
>
> module ClassMethods
>
> def using(hash)
> Class.new do
> @options = hash
> end
> end
>
> def options
> @options
> end
>
> end
> end
>
> class Opportunities
> include ClassFactory
> end
>
> Foo = Opportunities.using({one: 1, two: 2, three: 3})
> Bar = Opportunities.using({four: 4, five: 5, six: 6})
>
> p Foo.options
> p Bar.options
>
> --output:--
> prog.rb:28:in `<main>': undefined method `options' for Foo:Class
> (NoMethodError)
Your new class does not inherit module ClassMethods, that's why.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Lars Olsson <lasso@lassoweb.se> |
|---|---|
| Date | 2011-04-12 01:25 -0700 |
| Message-ID | <fda30fbb-e519-4373-bda6-c3e6b2af7c73@r6g2000vbo.googlegroups.com> |
| In reply to | #2663 |
On 12 Apr, 09:00, Robert Klemme <shortcut...@googlemail.com> wrote:
> On Tue, Apr 12, 2011 at 4:48 AM, 7stud -- <bbxx789_0...@yahoo.com> wrote:
> > ...but then you could do this:
>
> > module ClassFactory
> > def ClassFactory.included(includer)
> > includer.extend(ClassMethods)
> > end
>
> > module ClassMethods
>
> > def using(hash)
> > Class.new do
> > @options = hash
> > class << self
> > attr_reader :options
> > end
> > end
> > end
>
> > end
> > end
>
> > class Opportunities
> > include ClassFactory
> > end
>
> I think we can do this simpler if you want to reuse that options
> creation functionality:
>
> module ClassFactory
> attr_reader :options
>
> def using(opts)
> Class.new(self).tap do |cl|
> cl.instance_variable_set '@options', opts.freeze
> end
> end
> end
>
> class Opportunities
> extend ClassFactory
> end
>
> irb(main):020:0> foo = Opportunities.using(foo: 1, bar: 2)
> => #<Class:0x10952bc0>
> irb(main):021:0> foo.options
> => {:foo=>1, :bar=>2}
> irb(main):022:0> foo.ancestors
> => [#<Class:0x10952bc0>, Opportunities, Object, Kernel, BasicObject]
>
>
>
> > I really wanted to write that like below, but it doesn't work??
>
> > module ClassFactory
> > def ClassFactory.included(includer)
> > includer.extend(ClassMethods)
> > end
>
> > module ClassMethods
>
> > def using(hash)
> > Class.new do
> > @options = hash
> > end
> > end
>
> > def options
> > @options
> > end
>
> > end
> > end
>
> > class Opportunities
> > include ClassFactory
> > end
>
> > Foo = Opportunities.using({one: 1, two: 2, three: 3})
> > Bar = Opportunities.using({four: 4, five: 5, six: 6})
>
> > p Foo.options
> > p Bar.options
>
> > --output:--
> > prog.rb:28:in `<main>': undefined method `options' for Foo:Class
> > (NoMethodError)
>
> Your new class does not inherit module ClassMethods, that's why.
>
> Kind regards
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/
Hello again!
I've now incorporated your solution into my code and it works very
well. I still have a small question though. What's the reason for
freezing the options? I can see no obvious explanation for it except
that one might not want to change them by accident. Or is there
another reason for this?
/lasso
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-04-12 03:51 -0500 |
| Message-ID | <BANLkTi=72vZU3t8wBPY4Wjzwc13AJKwPgA@mail.gmail.com> |
| In reply to | #2670 |
On Tue, Apr 12, 2011 at 10:30 AM, Lars Olsson <lasso@lassoweb.se> wrote: > I've now incorporated your solution into my code and it works very > well. Fine! (Btw, which one did you pick?) > I still have a small question though. What's the reason for > freezing the options? I can see no obvious explanation for it except > that one might not want to change them by accident. Or is there > another reason for this? No, that's the only reason. Note also that this is not 100% safe because elements in the Hash are not frozen so for a more robust solution you would need to recursively freeze everything contained in the Hash. I still like it to freeze the Hash to avoid simple errors and document in code that this is really meant to be constant. (At least that's what I guessed you wanted them to be.) Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 13:14 -0500 |
| Message-ID | <603155d85e9b5df9cd7a2ff90951f539@ruby-forum.com> |
| In reply to | #2670 |
Lars Olsson wrote in post #992249:
> Hello again!
>
I was fooling around with your original requirement:
> I want to create a class method that takes a bunch
> of options and returns a singleton class with those
> options set,
..and I think I was probably running into the same problems you were:
class Object
def singleton_class
class << self
self
end
end
end
class Opportunities
def self.using(options)
# Store options in singleton class variable
# @options and then return singleton class
obj = self.new
singleton = obj.singleton_class
singleton.instance_variable_set(:@options, options)
singleton.class_eval do #<----PROBLEM HERE
def options
@options
end
end
singleton
end
end
Foo = Opportunities.using(one: 1, two: 2, three: 3)
Bar = Opportunities.using(four: 4, five: 5, six: 6)
p Foo.options
p Bar.options
--output:--
prog.rb:37:in `<main>': undefined method `options' for
#<Class:#<Opportunities:0x88cfef8>> (NoMethodError)
The problem is that options() is an instance method of the singleton
class, but in this line:
Foo.options
Foo is the singelton class, and therefore options() is being called as a
class method of the singleton class. A class method of a singleton
class??!! You can actually create such a thing in ruby:
class Object
def singleton_class
class << self
self
end
end
end
class Opportunities
def self.using(options)
# Store options in singleton class variable
# @options and then return singleton class
obj = self.new
singleton = obj.singleton_class
singleton.send(:instance_variable_set, :@options, options)
singleton.singleton_class.class_eval do #<---SOLUTION***
def options
@options
end
end
singleton
end
end
Foo = Opportunities.using(one: 1, two: 2, three: 3)
Bar = Opportunities.using(four: 4, five: 5, six: 6)
p Foo.options
p Bar.options
--output:--
{:one=>1, :two=>2, :three=>3}
{:four=>4, :five=>5, :six=>6}
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 13:38 -0500 |
| Message-ID | <5f107195d62547c768594590a95d3530@ruby-forum.com> |
| In reply to | #2699 |
7stud -- wrote in post #992354: > The syntax is a little simpler doing this: > > class << singleton > attr_reader :options #(self.)attr_reader, where self=singleton > end ..actually, class << singleton puts us in the singleton class of singleton, so that should say "self = singleton class of singleton". -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 13:43 -0500 |
| Message-ID | <65eab2e55acd4917573606e85963a305@ruby-forum.com> |
| In reply to | #2663 |
Robert K. wrote in post #992235: >> >> --output:-- >> prog.rb:28:in `<main>': undefined method `options' for Foo:Class >> (NoMethodError) > > Your new class does not inherit module ClassMethods, that's why. > I figured out the problem after I posted--including the module ClassFactory creates class methods in Opportunities--not the anonymous class that using() returns. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-12 19:29 -0500 |
| Message-ID | <1ab35d34d631a49a00d7c9335a715a19@ruby-forum.com> |
| In reply to | #2616 |
and:
class <<singleton
attr_reader :options
end
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Lars Olsson <lasso@lassoweb.se> |
|---|---|
| Date | 2011-04-13 01:49 -0700 |
| Message-ID | <844ec45a-a24d-44b9-b73c-44fc9af2a43b@u12g2000vbf.googlegroups.com> |
| In reply to | #2714 |
On 13 Apr, 02:29, 7stud -- <bbxx789_0...@yahoo.com> wrote:
> and:
>
> class <<singleton
> attr_reader :options
> end
>
> --
> Posted viahttp://www.ruby-forum.com/.
I'm happy to see that is was possible to do this in so many ways :)
For what it is worth, here's what I finally settled for:
class Opportunities
@options = {:opt1 => :default, :opt2 => :default, :opt3
=> :default}.freeze
def self.options
@options
end
def self.using(options)
Class.new(self) do
@options = superclass.options.merge(options).select do |key|
superclass.options.has_key?(key)
end.freeze
end
end
end
Thank you all for showing how crazy simple this stuff is to do in
ruby!
/lasso
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-13 19:32 -0500 |
| Message-ID | <2bdfa1bebeed2a8a82ae8c749f7e5c56@ruby-forum.com> |
| In reply to | #2616 |
Too many variables named 'options'! -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-13 19:49 -0500 |
| Message-ID | <3ceb1b0bbd68fdd258d5a1f2fdaf6402@ruby-forum.com> |
| In reply to | #2616 |
Try something like this:
def using(new_options)
Class.new(self) do
old_options = superclass.options
@options = old_options.merge(new_options).select do |key|
old_options.has_key?(key)
end.freeze
end
end
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.ruby
csiph-web