Hacker News new | past | comments | ask | show | jobs | submit login
How to Dynamically Create Instance Variables in Ruby (akshaykhot.com)
65 points by thunderbong on July 28, 2023 | hide | past | favorite | 25 comments



This technique is useful in Rails if you need to assign instance variables that have the name of a model.

Here’s an example: https://github.com/rubymonolith/demo/blob/main/app/controlle...


If you just need to pass data around in something more rigid than a hash, you can use a struct:

  someone = Struct.new(*%i[name age craze whatever]).new(?Ô, 128, {color: :pink}, :nevermind)

Or even an open struct for more flexibility, if performance is not critical and an additional require doesn’t matter.

https://ruby-doc.org/stdlib-3.1.0/libdoc/ostruct/rdoc/OpenSt...


Ruby 3.2 has `Data.define`, which is an even better way of doing this: https://docs.ruby-lang.org/en/3.2/Data.html


Nice, it's attrs/dataclass from Python.


Awesome, thanks for pointing it.


This seems infinitely better than dynamically adding instance attributes. Dynamic instance attributes was absolutely the worst thing about "old school" Python programming. The language, community, and ecosystem are much better off now that it's considered bad style and is strongly discouraged. Unfortunately we are stuck with it in the stdlib logging framework and the Tornado web framework, but it's mercifully absent just about everywhere else, and help platforms will almost universally discourage people from doing it.


Ruby websites like GitHub generally seem nicer and more elegant that Python/Django ones like python.org or Instagram. The latter are clunky.

I wonder if the language influences the aesthetics. Python is boring and clunky as well.

Some people here criticize meta-programming. I was one of them until I read the gorgeous Homebrew configuration files. Of course, don't overdo it.


I mean if we talk about the creators/inspiration around these languages we have creators of Ruby from Japan where things are tidy, elegant and mindful of others. An inspiration for the name of Python is from Monty Python creators of the Ministry of Silly Walks which is kinda clunky looking when you watch it. https://www.youtube.com/watch?v=eCLp7zodUiI

Thanks for reading my highly technical analysis.


Japanese web design certainly isn’t tidy or elegant


> I wonder if the language influences the aesthetics.

The community does. You’ll notice that JavaScript command line tools are much fancier than other languages, with emojis and cool spinners. Being that many JS programmers are web developers there’s a sense of aesthetics baked in the community. Other communities don’t have to care about “pretty” in their day-to-day so their tools reflect it.


The languages don't directly influence the aesthetics. Rather, there's a culture that precedes a language, and the audience it attracts, and it defines the marketing of that language, among other things. Of course, there's always interaction and mutual feedback. But I'm just saying I don't see this as the high order bit.

In the case of Ruby, in fact the culture didn't come from Ruby, but Ruby on Rails, which marketed almost exclusively to non-programmers. "Classic" programmers suck at design.


Probably just selection bias. Ruby is way more niche than Python so Ruby programmers are less likely to be complete beginners.

It's quite a bit problem for Python actually IMO. It is so popular among beginners that a lot of libraries and StackOverflow answers are beginner-quality.


Python is almost as good as Ruby. They have slightly different takes on a few things (taaaaabs) but you can easily jump from one to the other.


Almost being the key word here ;)

I tried testing in Python years ago and found the likes of PyTest etc to be light years behind what RSpec and even Minitest offer.


This! Python testing ergonomics are terrible, worse than Js.

It’s a reason I love Elixir.


> Disclaimer: The point of the post is not that we should all be creating instance variables dynamically from now on, but just to show one way to do it for those rare cases when you actually do need it

Make sure you absolutely need it

Trying to track variable names and finding specific code when they are being generated dynamically can quickly become nightmare


Not really a problem I've come across but I'd say if you're passing 100 arguments to your initialize method, you probably need to refactor somewhere? Personally, I like seeing the instance variables I have rather than having them hidden in a magic list of attributes.


Or an... array? Like why bother?


This is beautiful, but "ugly" at the same time.

For example, it allows you to monkey patch at runtime any library that you install.

Compare with Javascript, i'm not sure if you can just install a package, patch it at runtime (like this article is about) to match your need.

In some sense, this is similar to OOP inheritance and overloading, but for intance variables.

That's why most of Ruby startups tends to go faster than other languages, because all Ruby classes is hackable at runtime.


This kind of thing is possible in both python and javascript, it's just generally discouraged.


It’s actually easier in JavaScript compared to either language….

var foo = {}

foo.bar = “hello new property”

console.log(foo.bar)


Your example is not equivalent to the Ruby code. You’re just assigning a value to a property which is always exposed, you’re showing getters/setters. The instance variables are not by default exposed or accessible outside the class/object.


On the other hand...

foo = {bar: "123"}; with (foo) eval("console.log(bar)")


> No such shorthand exists in Ruby (and I'm glad that Ruby doesn't have the feature bloat like TypeScript and C#)

I find that while Ruby’s syntax may have a smaller surface area there are so many more ways to do things than with other languages that I reach for others first.

Also Ruby encourages so much metaprogramming that it can be very very difficult to work out where a behavior comes from. You _really_ have to document everything and getting a good editor config for Ruby is very important. That said I still struggle to get basic autocomplete working with Ruby in vs code


I use ruby-lsp and solargraph and copilot. Personally I'm rarely tempted to get very meta at work, but side projects are another thing entirely. I think one project has six DSLs?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: