Can Ruby do this magic... elegantly

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.
Thanks,
James

class Bas
  @__struct__ = Struct.new(:attribute, :another_attribute)

  class << self
    def method_missing(sym, *args)
       @__struct__.send(sym, *args) if @__struct__.respond_to?(sym)
    end
  end
end

That should work.

-austin

···

On 11/11/06, J2M <james2mccarthy@gmail.com> wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

harp:~ > cat a.rb
     class Module
       def struct_attrs struct
         singleton_class = class << self
           self
         end
         singleton_class.module_eval{ struct.members.each{|m| attr_accessor m} }
       end
     end

     class Bas
       foo = Struct.new :attribute, :another_attribute
       bar = foo.new

       struct_attrs foo
     end

     Bas.attribute = "a value"
     p Bas.attribute

     harp:~ > ruby a.rb
     "a value"

-a

···

On Sun, 12 Nov 2006, J2M wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.
Thanks,
James

--
my religion is very simple. my religion is kindness. -- the dalai lama

J2M wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute
Kind of like doing module_functions but that doesn't work inside a
class.

  Foo = Struct.new(:attribute, :another_attribute)

  class Bas
    extend Foo.to_module
  end

Ha! Only if it were so easy! :wink: Actaully if one had access to Ruby's
source it would rather trivial (hint). In anycase to par down Ara's
solution to it's core:

   Foo = Struct.new :attribute, :another_attribute

   class Bas
     class << self
       attr_accessor *Foo.members
     end
   end

Note the use of the constant which eases access by avoiding
(class<<self;self;end).class_eval.

T.

J2M wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.

I don't know why people make it so complicated. :slight_smile: All these are easier than other approaches suggested so far:

Foo = Struct.new(:attribute, :another_attribute)
class Bas < Foo
end

class Bas < Struct.new(:attribute, :another_attribute)
end

or even

Bas = Struct.new(:attribute, :another_attribute) do
   def another_method() end
end

Kind regards

  robert

Robert, T, A & Austin;

A plethora of choices. All while I slept too :wink:

Thank you all.
James

Hi--

···

On Sun, 12 Nov 2006, Robert Klemme wrote:

J2M wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.

I don't know why people make it so complicated. :slight_smile: All these are easier than other approaches suggested so far:

Foo = Struct.new(:attribute, :another_attribute)
class Bas < Foo
end

class Bas < Struct.new(:attribute, :another_attribute)
end

or even

Bas = Struct.new(:attribute, :another_attribute) do
def another_method() end
end

You're adding instance methods to Bas rather than to Bas's singleton
class, though. The OP wants to do:

   Bas.attribute = "a value"

David

--
                   David A. Black | dblack@rubypal.com
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

dblack@wobblini.net wrote:

Hi--

J2M wrote:

I would like to be able to be able to include instance methods of a
Struct into a class. e.g.

foo = Struct.new(:attribute, :another_attribute)
bar = foo.new

class Bas

  some_ruby_magic

end

So that I can then do

Bas.attribute="a value"
Bas.attribute

Kind of like doing module_functions but that doesn't work inside a
class.

I don't know why people make it so complicated. :slight_smile: All these are easier than other approaches suggested so far:

Foo = Struct.new(:attribute, :another_attribute)
class Bas < Foo
end

class Bas < Struct.new(:attribute, :another_attribute)
end

or even

Bas = Struct.new(:attribute, :another_attribute) do
def another_method() end
end

You're adding instance methods to Bas rather than to Bas's singleton
class, though. The OP wants to do:

  Bas.attribute = "a value"

Oh, ok then I misinterpreted that. I read "include instance methods into a class" as including them as instance methods. My bad. Sorry for the noise.

In this particular case, /if/ the aim is to define attribute accessors a direct definition is probably the easiest solution

class Bas
   class <<self
     attr_accessor :attribute, :another_attribute
   end
end

Regards

  robert

···

On Sun, 12 Nov 2006, Robert Klemme wrote:

I got the final solution down to this which I think is rather elegant;

   class Bas < Struct.new :attribute, :another_attribute
     class << self
       attr_accessor *Bas.members
     end
   end

I love this languate; and now really appreciate the power of the
singleton class.

Thanks.

J2M wrote:

I got the final solution down to this which I think is rather elegant;

   class Bas < Struct.new :attribute, :another_attribute
     class << self
       attr_accessor *Bas.members
     end
   end

    class Bas < Struct.new :attribute, :another_attribute
      class << self
        attr_accessor *members
      end
    end

Do you realize that you are adding #attribute and #another_attribute at
both the instance level and the class level, and niether will reference
tha same values? I.e.

  Bas.attribute = 1
  bas = Bas.new
  bas.attribute = 2
  Bas.attribute #=> 1
  bas.attribute #=> 2

T.

Trans wrote:

Do you realize that you are adding #attribute and #another_attribute at
both the instance level and the class level, and niether will reference
tha same values? I.e.

  Bas.attribute = 1
  bas = Bas.new
  bas.attribute = 2
  Bas.attribute #=> 1
  bas.attribute #=> 2

Yes, this is the behaviour I want. I am not actually creating any
instances. I just use it as a base class and inherit from it.

Thanks,
James

Trans wrote:

J2M wrote:

I got the final solution down to this which I think is rather elegant;

   class Bas < Struct.new :attribute, :another_attribute
     class << self
       attr_accessor *Bas.members
     end
   end

    class Bas < Struct.new :attribute, :another_attribute
      class << self
        attr_accessor *members
      end
    end

Do you realize that you are adding #attribute and #another_attribute at
both the instance level and the class level, and niether will reference
tha same values? I.e.

  Bas.attribute = 1
  bas = Bas.new
  bas.attribute = 2
  Bas.attribute #=> 1
  bas.attribute #=> 2

Also, what is the point in creating a Struct in this case when you're basically only using member names?

  robert

Robert Klemme wrote:

Also, what is the point in creating a Struct in this case when you're
basically only using member names?

  robert

Good spot :-/

I started out using Struct as I wanted the extra methods for free and
was creating instances off of it. I have just re-worked this and just
mix enumerable into the class and get most of what I got from struct,
so have strayed quite a way from the original question.

James.