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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs