Issue #16122 has been updated by mame (Yusuke Endoh).


I couldn't understand what is "value object", and I found: https://martinfowler.com/bliki/ValueObject.html
Please do not assume that everybody knows such an essay ;-)
No one pointed out the article during the developer's meeting, so we cannot understand what you want.

I have some comments:

* Why don't you start it with a gem?  It may be useful for your case, but I'm not sure if it is useful for many people so that it deserves a built-in feature.  And the design of `Struct::Value` is not clear to me (e.g., non-Enumerable is trade off; is it really useful for many cases?).If your gem become so popular, we can import it as a built-in feature.
* The behavior of `Struct::Value` is too different from `Struct`.  Another class name (like `ValueClass` or `NamedTuple` or what not) looks more suitable.
* What you (first) want is called "structural equality" in other languages (OCaml, F#, C#, TypeScript, Kotlin, as far as I know).  Also it resembles "namedtuple" in Python.  You may want to study them.

BTW, I understand the motivation of the proposal.  I want "structural equality" in Ruby.  Personally, I often write:

```
class Point3D
  include StructuralEquality
  def initialize(x, y, z)
    @x, @y, @z = x, y, z
  end
end

foo1 = Point3D.new(1, 2, 3)
foo2 = Point3D.new(1, 2, 3)
p foo1 == foo2 #=> true
h = { foo1 => "ok" }
p h[foo2] #=> "ok"
```

(The definition of `StructuralEquality` is here: https://github.com/mame/ruby-type-profiler/blob/436a10787fc74db47a8b2e9db995aa6ef7c16311/lib/type-profiler/utils.rb#L8-L31 )

But, I'm unsure if it deserves a built-in feature.

----------------------------------------
Feature #16122: Struct::Value: simple immutable value object
https://bugs.ruby-lang.org/issues/16122#change-81271

* Author: zverok (Victor Shepelev)
* Status: Feedback
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Currently, **Struct** behaves like a *value object*:
* it is created from simple attributes;
* its equality and representation based only on those attributes.

But also, it behaves like a **mutable object** (allows to set attributes), and **as a kind-of collection** (includes `Enumerable`, has `to_a` and `[]` accessors).

And while `Struct` is kinda useful as is, I found that in a lot of cases what I really *mean* creating a Struct is just creating a pure, immutable value object, that is *just it*. There are a lot of gems that go this or that far to provide "value object" concept, but in fact, the concept is so simple that typically nobody will install the gem to just have it -- that's why I believe it should be in language core.

So, here is the proposal **and its C implementation:**

* Class `Struct::Value`, which shares most of the implementation with a `Struct` (but is neither subclass nor superclass of it);
* Unlike struct, it is: 
  * Not Enumerable;
  * Immutable;
  * Doesn't think of itself as "almost hash" (doesn't have `to_a`, `values` and `[]` methods);
  * Can have empty members list (fun fact: `Struct.new('Foo')` creating member-less `Struct::Foo`, is allowed, but `Struct.new()` is not) to allow usage patterns like:

```ruby
class MyService
  Success = Struct::Value.new(:results)
  NotFound = Struct::Value.new
end
```
`NotFound` here, unlike, say, `Object.new.freeze` (another pattern for creating "empty typed value object"), has nice inspect `#<value NotFound>`, and created consistently with the `Success`, making the code more readable.

---Files--------------------------------
struct_value.patch (18.6 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>