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
First Post!
Eiji
There are lots of packages dedicated for structs:
Search results for: struct access @ hex.pm
Many of them adds support for Access behaviour, so you can use it with *_in functions like get_in.
That’s rather not about FP or OO paradigms, but about struct documentation. Some parts may be private, so if they are not well documented then the developer assumes that specific keys are private and should be not changed by hand. Documenting all fields would require a support for them in future as long as you would not hard deprecate them.
User-defined types | Typespecs reference @ Elixir documentation
Not really objective if you do not update the object … No worries for that. If it’s not a “simple struct” then you can follow Phoenix generators i.e. use context-based functions to fetch data from database and use struct (in ecto it’s called schema) module to define other helper functions like get_full_name etc.
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.
Popular in Discussions
Other popular topics
Chat & Discussions>Discussions
Latest on Elixir Forum
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









