Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.ruby > #2616 > unrolled thread

Copying parameters to singleton class

Started byLars Olsson <lasso@lassoweb.se>
First post2011-04-11 02:19 -0700
Last post2011-04-14 12:07 -0500
Articles 20 on this page of 23 — 4 participants

Back to article view | Back to comp.lang.ruby


Contents

  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 →


#2616 — Copying parameters to singleton class

FromLars Olsson <lasso@lassoweb.se>
Date2011-04-11 02:19 -0700
SubjectCopying 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]


#2618

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-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]


#2654

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2655

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2662

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-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]


#2700

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2713

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2619

FromJesús Gabriel y Galán <jgabrielygalan@gmail.com>
Date2011-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]


#2621

FromLars Olsson <lasso@lassoweb.se>
Date2011-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]


#2656

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2663

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-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]


#2670

FromLars Olsson <lasso@lassoweb.se>
Date2011-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]


#2672

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-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]


#2699

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2701

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2702

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2714

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2739

FromLars Olsson <lasso@lassoweb.se>
Date2011-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]


#2801

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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]


#2804

From7stud -- <bbxx789_05ss@yahoo.com>
Date2011-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