OpenStruct is now officially discouraged

The “Boutique Inventory Improvements” exercise demonstrates the OpenStruct concept, but this is now officially discouraged in favour of Struct for performance and security reasons:

“For all these reasons, consider not using OpenStruct at all.”

Also see RubyDoc.info: Class: RuboCop::Cop::Style::OpenStructUse – Documentation for rubocop (1.75.6) – RubyDoc.info

Recommendation: replace the OpenStruct concept with Struct.

1 Like

That is coming from Rubocop and should be taken with a grain of salt, also even Rubocop does not cite the “officially discouraged” inference.

I have unofficially discouraged use of both for a lot of reasons. For a lot of reasons.

But for purposes of exploring the language, and until it is removed from the language, the exploration of this is still good.

I think @iHiD commonly uses Structs of either flavor, and I (without checking right this moment) suspect that he has some opinions on this, as I believe he was a founding contributor to this exercise.

It is definitely useful to keep it as it is for the mentoring value, though, even if your (the collective) educated opinions are different than mine.

Not just from Rubocop; the quoted line above is from the official Ruby documentation, as linked: “For all these reasons, consider not using OpenStruct at all.” Given the security concerns, teaching this is encouraging bad practises.

Summary statement: We could point this out, in the documentation, but still teach it. Teaching something in itself is not teaching bad practices. Teaching bad practices is teaching bad practices.

Like I mentioned earlier, not really a fan of Struct and OpenStruct, but I understand the value when used responsibly. I usually solve in other ways that give the same flexibility, or I clean up those objects by undefining the things I do not want or need from it. (And since that is extra work, I usually end up doing something else.)


Yes, I read your links (regardless if the click indicator indicates no clicks, it does not track my movements from here), and am aware of what you quoted.

Still, teaching anything does not encourage bad practices, unless you explicitly state “and you should use this”. I literally say the opposite when I mentor this exercise. I encourage people to not use this, but think about what it does and if it is the right tool for the job, knowing what they learned about it. But I have no problems with teaching this, and when it may be suitable, plus all the things that it (in my opinion) over exposes, and the way that it works. I also teach method_missing which is not officially discouraged, as it were, but officially encouraged to be used when it is the right tool for the job.

An interpretation of “officially discouraged” has been on and off at least since 2009 for both Struct and OpenStruct. Teaching it is not teaching bad practices, but teaching bad practices is teaching bad practices.

Thanks for flagging this.

I think three things:

  1. This advice has been there for a few years - since 3.0 at least. I’m not sure anything massively has changed recently.
  2. I find OpenStruct really useful and use it a lot in production. But like everything, it’s important to understand the risk/rewards. So maybe adding a note that it should be used with care is wise?
  3. This is likely not a key topic in learning Ruby, but it is a useful thing to know IMO. If the syllabus was broader, it might matter less that this was here? I understand that with a smaller syllabus, having this exercise makes it feel much more important than other topics.

I don’t think I want to remove this, but I’d be in favour of adding a line to the introduction and about like “Using OpenStruct with untrusted data can be a security risk. Please read these caveats and use it with care” (or something)?

@xanni Would you like to PR that? :slight_smile:

2 Likes

I agree that OpenStruct has its uses provided the risks are fully understood. My concern is that if we don’t have a Struct example, we’re promoting the less performant and safe alternative which is then establishing a poor foundation for novice programmers. If we don’t teach Struct at all, I’d rather submit a PR to change this example and concept from OpenStruct to Struct.

Struct being more performant and.or secure has been one of the things that sways back and forth over the years as well. One of the reasons, I think, that there are both of them.

Today, it may be true, yesterday it wasn’t, and tomorrow it may again not be.

I am looking forward to a PR as well!

I could start working on a hash concept during the Summer, and then we could teach hash first and then have branch to openstruct/struct and perhaps detail when you would use openstruct/struct/hash in Ruby in the openstruct/struct concept.

1 Like

Yep. I’d be happy to see this, and @xanni I’d be happy to see a seperate Struct exercise too! But I wouldn’t want to change the existing one as its been solved a lot already and would break existing solutions :slight_smile:

Not necessarily, if the tests are modified to accept either! :slight_smile:

I would love to see an exercise where Data class is being used. Teaching Hash first then Data, then Struct… I would definitely include Data in the mix there.

Oh, I like that.