Shelvacu
Shelvacu

Reputation: 4362

How to avoid instance variable initializing ugliness

I see this popping up all the time in my code

class Foo
  def initialize(foo)
    @foo = foo
  end
  #...
end

This isn't too bad, but it gets worse:

class Foo
  def initialize(foo,baz,bar,a,b,c,d)
    @foo = foo
    @baz = baz
    @bar = bar
    #etc...

You can sortof get around this by doing something like

@foo, @baz, @bar = foo, baz, bar

But even that feels wrong and is annoying to type. Is there a better way to define instance variables according to arguments?

Edit: There seem to be 2 distinct solutions to this problem. See:

Upvotes: 1

Views: 161

Answers (5)

spickermann
spickermann

Reputation: 106932

You might want to consider using a Struct:

class Foo < Struct.new(foo,baz,bar,a,b,c,d)
end

foo = Foo.new(1,2,3,4,5,6,7)
foo.bar #=> 2

No need to define an extra initialize method at all...

Upvotes: 7

DGM
DGM

Reputation: 26979

The fattr gem was recently endorsed on Ruby Tapas to help solve this problem. Another consideration though, is whether there are too many things being passed into the initializer. It could be that this class is doing too much and needs to be broken into smaller pieces.

Upvotes: 0

Antarr Byrd
Antarr Byrd

Reputation: 26091

def initialize args
  @foo, @baz, @bar = *args
end

Upvotes: 3

media-slave24
media-slave24

Reputation: 256

I think there are 3 ways to make initialization of instance variables shorter:

  1. Use Struct or OpenStruct.
  2. Use ruby's parallel assignment.
  3. Use metaprogramming to make a macro like this.

Upvotes: 0

Tobias Cohen
Tobias Cohen

Reputation: 20000

Yes, that's the preferred way to initialize instance variables in Ruby. It can be annoying to type, but it's a well understood pattern. As always in Ruby, using metaprogramming to automate it away is possible, but will make your code harder to follow.

I'd also argue that it's probably a good thing for a class to look ugly when it's taking more than two or three arguments. If your class depends on six different things to function, it's a strong candidate for refactoring.

Upvotes: 3

Related Questions