ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: daniel@dan42.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:94665] [Ruby master Feature#16122] Struct::Value: simple immutable value object
Date: Thu, 29 Aug 2019 12:50:22 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-81269.20190829125021.18093e7dd2f989a0@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-16122.20190823174036@ruby-lang.org

Issue #16122 has been updated by Dan0042 (Daniel DeLorme).


If I understand correctly, the idea is to have `X=Struct::Value.new(:x,:y,:z)` which is strictly equivalent to

```ruby
class X
  def initialize(x=nil, y=nil, z=nil)
    @x,@y,@z = x,y,z
  end
  attr_reader :x, :y, :z
end
```

Or was there some nuance I didn't catch?

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

* 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/

  parent reply	other threads:[~2019-08-29 12:50 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-16122.20190823174036@ruby-lang.org>
2019-08-23 17:40 ` [ruby-core:94508] [Ruby master Feature#16122] Struct::Value: simple immutable value object zverok.offline
2019-08-24  6:55 ` [ruby-core:94526] " eregontp
2019-08-24 10:17 ` [ruby-core:94527] " zverok.offline
2019-08-24 10:37 ` [ruby-core:94528] " zverok.offline
2019-08-29  8:01 ` [ruby-core:94661] " matz
2019-08-29  9:35 ` [ruby-core:94662] " zverok.offline
2019-08-29 12:50 ` daniel [this message]
2019-08-29 12:55 ` [ruby-core:94666] " zverok.offline
2019-08-29 14:14 ` [ruby-core:94667] " mame
2019-08-29 14:46 ` [ruby-core:94668] " zverok.offline
2019-08-29 20:33 ` [ruby-core:94672] " zverok.offline
2019-08-30  0:09 ` [ruby-core:94674] " naruse
2019-08-30  7:05 ` [ruby-core:94679] " zverok.offline
2019-08-30 13:15 ` [ruby-core:94683] " daniel
2019-08-30 14:55 ` [ruby-core:94685] " zverok.offline
2019-08-30 18:26 ` [ruby-core:94690] " daniel
2019-09-03 15:56 ` [ruby-core:94762] " dementiev.vm
2019-09-07 19:56 ` [ruby-core:94832] " zverok.offline
2019-10-30  2:46 ` [ruby-core:95586] " daniel
2019-11-28  8:40 ` [ruby-core:96017] " matz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-81269.20190829125021.18093e7dd2f989a0@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).