chrisliaw
Is it common to create accessor functions for struct fields?
Hi,
I’m wondering is it my thinking process or this is the norm among the Elixir developer for the use of Struct and accessor functions (get/set)?
For example:
defmodule Session do
defstruct [:name]
# this is just example as there might be
# more transformation before putting the value inside the struct
def set_name(%Session{} = session, name) do
%Session{session | name: String.upcase(name)}
end
# likewise there might be more transformation before returning the value
def get_name(%Session{} = session) do
String.downcase(session.name)
end
end
The reason to create the accessor is somehow (probably OO habit die hard, or not?) along the argument of to isolate the user of the struct to access the key directly to allow future changes to the struct key without affecting the caller. For example later if the struct change the field to :customer_name, caller using the get_name() function would not aware the field has changes its name.
But this pretty much feels like OO thinking in me. Is that an alternative or is that a sensible way to design this structure?
Cons is now get/set is everywhere inside the struct module.
Thanks!
Regards
Most Liked
krasenyp
Speaking of dependency injection, in FP it’s called an argument to a function. I really don’t understand why most people writing Elixir just don’t like passing dependencies via function arguments. If you don’t state what your logic depends on, it depends on everything and it’s almost impossible to isolate and test.
sodapopcan
Thank you! I kept seeing people talking about DI in this thread and another and kept thinking I was missing something.
Ehn, “constructor” is a legit FP term
I do hate when people say “method” though, mostly because I feel that deep down they really do believe they are somehow still methods ![]()
Near the end of my time with OO, I started feeling getters and setters were pretty pointless, feeling like a holdover over for when code like this was acceptable:
user = new User
user.set_name("Bender Bending Rodríguez")
user.set_email("bender@planetexpress.com")
Maybe it still is? I dunno. But I view it as a giant smell if method names prefixed with get_ and set_ doing anything or than returning the raw property value. It’s just plain confusing. If you do this, you not longer have a “getter” or “setter” and the method name should reflect this.
In terms of renames, I’ve never been in a situation where renaming a field didn’t result in a project-wide rename. I haven’t worked on any truly massive projects before (biggest was ~1 million lines of Ruby) and of course it would be different for an app vs a library. I have heard someone on this forum lament not being able to change the name of a field in their library, but there are still other ways to deal with the mismatch (which I believe have been alluded to already?)
So many other thoughts on this thread but I’ll leave it at that!
D4no0
If you get out of your head the idea that tying data structures + behavior to modules is a good idea, you will understand that operating with data structures directly, without tying them to additional logic that is part of the same module, is easier to reason about in the code and more maintainable.
I honestly don’t like the fact that structs are tied to a module, there are technical reasons why it was done like this, however at the same time it sends a wrong message to people coming from OOP languages. The scope of the structs is to have something that resembles enforceable types, that can be checked easily by tools like dialyzer, tying behavior to those types is not the most optimal way to write code.
If you are just starting out, my advice is to just avoid using structs until you get a good hang on how to write elixir, use guards/pattern match to achieve the same guarantees structs offer. If you’ll use data structures that are not tied to any modules for some time, it will start to click in place the ideology where you design pipelines that transform data, instead of imperative logic tied to a module.
dimitarvp
If you’re asking if people regularly create struct getters / setters in Elixir then I’d say no.
There are legitimate exceptions when you need calculated values or you need to massage the value but they always were the very small minority in my work.
I’m seeing no reason to generate them, too. Elixir is quite terse; whenever you need a few of them, typing them out still looks like the fastest way of doing it.
felix-starman
This reminds me of a Scope struct that a coworker wrote.
It is still just a data structure with keys for the current user struct, the user permissions/roles, and a few other things like the organization.
It used guards heavily for the “important parts” but after the guard matched in the function head or in the function body, digging into the keys wasn’t a big deal because the compiler would complain if you tried to access keys that shouldn’t exist.
Modifying that Scope struct when logging in, or authorizing them, was done with setters, but that was more because of the sensitive nature of the use case and consistency, not because of the an Elixir idiom.







