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

On 11/11/06, J2M [email protected] wrote:

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.

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 Sun, 12 Nov 2006, J2M wrote:

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

 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

J2M wrote:

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

J2M wrote:

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.

[email protected] wrote:

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

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

Hi–

On Sun, 12 Nov 2006, Robert K. wrote:

I don’t know why people make it so complicated. :slight_smile: All these are easier than

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

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.

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.

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

Robert K. 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.

Trans wrote:

  class << self

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