Issue #19078 has been updated by ivoanjo (Ivo Anjo).
marcotc (Marco Costa) wrote in #note-14:
> > > Regarding threads I think we shouldn't inherit automatically in new threads, and rather do it explicitly (via Fiber.current.storage=) in the rare cases it's needed.
> >
> > I'm on the fence on this one. Usually the code spawning a thread, and the code using thread/fiber storage and needing it to be inherited are entirely decoupled. So you'd need to go convince all your dependencies that spawn threads (e.g. puma, sidekiq, etc) to add that one line of code. So I'd prefer if it was always implicitly copied.
>
> For cross-cutting concerns, like telemetry, automatic inheritance works best; asking a gem user to add one extra line per Fiber created would create room for error.
>
> I think thinking about the opposite use case, users that explicitly want a clean Fiber storage for newly created Fibers, would help here: how common is such use case? I can't think of a reason to have this as the default, except for saving on the performance cost of copying the storage.
To a bit of info on top of this (and disclaimer, I work with Marco [on the ddtrace gem](https://github.com/datadog/dd-trace-rb), one really nice property of the automatic inheritance is that it makes easy something that is otherwise quite hard to do automatically from regular Ruby code. E.g. to simulate such an automatic mechanism, one needs to monkey patch thread and fiber creation, which is really awkward and error-prone (ask me how I know this).
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100334
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
Pull Request: https://github.com/ruby/ruby/pull/6612
This is an evolution of the previous ideas:
- https://bugs.ruby-lang.org/issues/19058
- https://bugs.ruby-lang.org/issues/19062
This PR introduces fiber scoped variables, and is a solution for problems like <https://github.com/ioquatix/ioquatix/discussions/17>.
The main interface is:
```ruby
Fiber[key] = value
Fiber[key] # => value
```
The variables are scoped (local to) a fiber and inherited into child fibers and threads.
```ruby
Fiber[:request_id] = SecureRandom.hex(16)
Fiber.new do
p Fiber[:request_id] # prints the above request id
end
```
The fiber scoped variables are stored and can be accessed:
```ruby
Fiber.current.storage # => returns a Hash (copy) of the internal storage.
Fiber.current.storage= # => assigns a Hash (copy) to the internal storage.
```
Fiber itself has one new keyword argument:
```
Fiber.new(..., storage: hash, false, undef, nil)
```
This can control how the fiber variables are setup in a child context.
To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing <https://bugs.ruby-lang.org/issues/19077>.
## Examples
### Request loop
```ruby
Thread.new do
while request = queue.pop
Fiber.new(storage: {id: SecureRandom.hex(16)}) do
handle_request.call(request)
end
end
end
```
OR
```ruby
Thread.new do
while request = queue.pop
Fiber.current.storage = {id: SecureRandom.hex(16)}
handle_request.call(request)
end
end
```
--
https://bugs.ruby-lang.org/
Issue #19030 has been updated by vo.x (Vit Ondruch).
The emails are now containing too much empty lines. It already starts with the Redmine header which looks like:
~~~
----------------------------------------
Bug #19158: Ruby 3.1.3 installs wrong gemspec for debug gem
https://bugs.ruby-lang.org/issues/19158
* Author: deivid (David Rodríguez)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [arm64-darwin22]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
~~~
And the preformatted content is mostly unreadable due to this :/
----------------------------------------
Misc #19030: [ANN] Migrate lists.ruby-lang.org to Google Groups
https://bugs.ruby-lang.org/issues/19030#change-100333
* Author: hsbt (Hiroshi SHIBATA)
* Status: Closed
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
----------------------------------------
Our mailing-list server that is `lists.ruby-lang.org` is too old. And it's difficult to replace new server on AWS because building mail-service on AWS has a lot of limitations. I and @shugo decided to migrate lists.ruby-lang.org to Google Groups.
* In Nov-Dec 2022, we migrate the current list member to Google Groups of our google workspace.
* I hope to migrate to the last list-id, But I'm not sure we can do that.
* What will be used as an archive viewer has yet to be TBD status.
* blade is still down.
* I prefer plain text viewer like blade instead of google groups. Should we build it?
I will update this plan in this thread.
--
https://bugs.ruby-lang.org/
Issue #18996 has been updated by st0012 (Stan Lo).
hsbt (Hiroshi SHIBATA) wrote in #note-10:
>
> ```ruby
> Reline.completion_colors = {
> foreground: :white,
> background: :black,
> selected_text: :black,
> selection: :white
> }
> ```
I agree that `color` postfix is a bit redundant. But I still lean *slightly* toward having it because it makes passing values easier:
```rb
DialogRenderInfo.new(
pos: Reline::CursorPos.new(x, y),
contents: contents,
width: width,
**Reline.completion_colors
)
```
And when doing so, users get errors when they have typos or unsupported attributes in their `Reline.completion_colors`, for example.
But I'll take either one decided in the dev meeting.
----------------------------------------
Feature #18996: Proposal: Introduce new APIs to reline for changing dialog UI colours
https://bugs.ruby-lang.org/issues/18996#change-100332
* Author: st0012 (Stan Lo)
* Status: Open
* Priority: Normal
----------------------------------------
### TL;DR
I want to add APIs to `reline` for changing its dialog item's colors.
The APIs I want to add actually have been merged but becaue:
1. This is a design change
2. The maintainer @aycabta is not available to approve nor reject them
I want to raise it here to decide if we should:
1. Drop them
2. Modify them
3. Officiallty accept them
### Background
After version `1.4`, `irb` provides autocompletion support, which is a great feature and has increased many developers' productivity significantly.
But there's an user-experience issue: the completion items' UI colors (set in `reline`) [are not configurable](https://github.com/ruby/reline/blob/9ab5850444b49aff8e360a84e…. So depending on the user's terminal theme, some may find it hard to use because the background and the text having low-contrast colors, like this:
![](https://user-images.githubusercontent.com/3303032/148653612-e3dff786-1a10-4923-a0eb-3975cae10a7f.png)
And if that happens, the user has no way to fix it. This caused users to open issues like:
- https://github.com/ruby/irb/issues/351
- https://github.com/ruby/irb/issues/328
for being able to change it.
Some users even decided to disable it completely because the colors are unreadable to them. I have also seen people sharingtips for disabling this feature: [example](https://twitter.com/sdogruyol/status/1538512030449254400). So I believe it may be bothering many developers.
Personally I really like this feature but the background also bothers me:
![Screenshot 2022-09-07 at 22 55 12](https://user-images.githubusercontent.com/5079556/188990620-5ec7ba0c-97…
And that's why I want to improve it by making the colors configurable and potentially also by providing simple light/dark themes from `irb`.
### Proposal
For the dialog UI, there are 2 element states: `highlighted` and `default`. In `irb`'s case, the selected completion candidate will be `highlighted`, and the rest of options will be `default`. And each state has 2 colors: `foreground (text)` and `background (block)`.
This means the `reline` should allow `irb` and/or users to configure:
- Default items' foreground color
- Default items' background color
- Highlighted items' foreground color
- Highlighted items' background color
That brings us to these APIs:
- `Reline.dialog_default_fg_color`
- `Reline.dialog_default_bg_color`
- `Reline.dialog_highlight_fg_color`
- `Reline.dialog_highlight_bg_color`
And because `reline` only supports coloring through ANSI sequences, these APIs only has 8 available colors if we exclude their bright variants:
- Black
- Red
- Green
- Yellow
- Blue
- Magenta
- Cyan
- White
Given the limited options and also to prevent users from entering non-color ANSI sequences, these APIs only take color names directly:
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
Example:
```rb
Reline.dialog_default_bg_color = :black
puts Reline.dialog_default_bg_color_sequence #=> 40
Reline.dialog_default_fg_color = :white
puts Reline.dialog_default_fg_color_sequence #=> 37
Reline.dialog_highlight_bg_color = :blue
puts Reline.dialog_highlight_bg_color_sequence #=> 34
Reline.dialog_highlight_fg_color = :black
puts Reline.dialog_highlight_fg_color_sequence #=> 30
```
I have made a [proof of concept PR](https://github.com/ruby/irb/pull/380) on `irb` to show what these APIs can achieve if they or similar ones are adopted.
#### Related PRs
The related changes are made through multiple PRs:
- [Initial APIs PR by @pocari](https://github.com/ruby/reline/pull/413)
- [PR to improve the APIs and make them safer to use](https://github.com/ruby/reline/pull/454)
- [PR to rename the APIs](https://github.com/ruby/reline/pull/456)
#### Other Thoughts
This is more of a concern on the `irb` part, but to make the UI looks comfortable, I think it's better to follow these conditions:
1. An item's foreground and background colors should have high contrast with each other so the texts (foreground) are readable.
2. For the `highlighted` item, its background color should be easily distinguishable from the rest of `default` items.
3. When using dark terminal themes, the `default` items' background is better to be dark as well.
---Files--------------------------------
Screenshot 2022-10-18 at 15.25.36.png (9.7 KB)
--
https://bugs.ruby-lang.org/
Issue #19000 has been updated by p8 (Petrik de Heus).
If `dup` is chosen would it make sense to always allow `dup` methods to take arguments for consistency?
For example, it would allow the following code in Rails
```ruby
firm = Firm.first.dup
firm.account = Account.first
assert_queries(2) { firm.save! }
```
(https://github.com/rails/rails/blob/8e34831f97acd7448fd68a6ac130694079aea95…)
to be written as:
```ruby
firm = Firm.first.dup(account: Account.first)
assert_queries(2) { firm.save! }
```
----------------------------------------
Feature #19000: Data: Add "Copy with changes method" [Follow-on to #16122 Data: simple immutable value object]
https://bugs.ruby-lang.org/issues/19000#change-100324
* Author: RubyBugs (A Nonymous)
* Status: Open
* Priority: Normal
----------------------------------------
*As requested: extracted a follow-up to #16122 Data: simple immutable value object from [this comment](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/109815)*
# Proposal: Add a "Copy with changes" method to Data
Assume the proposed `Data.define` exists.
Seeing examples from the [[Values gem]](https://github.com/ms-ati/Values):
```ruby
# A new class
Point = Data.def(:x, :y)
# An immutable instance
Origin = Point.with(x: 0, y: 0)
# Q: How do we make copies that change 1 or more values?
right = Origin.with(x: 1.0)
up = Origin.with(y: 1.0)
up_and_right = right.with(y: up.y)
# In loops
movements = [
{ x: +0.5 },
{ x: +0.5 },
{ y: -1.0 },
{ x: +0.5 },
]
# position = Point(x: 1.5, y: -1.0)
position = movements.inject(Origin) { |p, move| p.with(**move) }
```
## Proposed detail: Call this method: `#with`
```ruby
Money = Data.define(:amount, :currency)
account = Money.new(amount: 100, currency: 'USD')
transactions = [+10, -5, +15]
account = transactions.inject(account) { |a, t| a.with(amount: a.amount + t) }
#=> Money(amount: 120, currency: "USD")
```
## Why add this "Copy with changes" method to the Data simple immutable value class?
Called on an instance, it returns a new instance with only the provided parameters changed.
This API affordance is now **widely adopted across many languages** for its usefulness. Why is it so useful? Because copying immutable value object instances, with 1 or more discrete changes to specific fields, is the proper and ubiquitous pattern that takes the place of mutation when working with immutable value objects.
**Other languages**
C# Records: “immutable record structs — Non-destructive mutation” — is called `with { ... }`
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-t…
Scala Case Classes — is called `#copy`
https://docs.scala-lang.org/tour/case-classes.html
Java 14+ Records — Brian Goetz at Oracle is working on adding a with copy constructor inspired by C# above as we speak, likely to be called `#with`
https://mail.openjdk.org/pipermail/amber-spec-experts/2022-June/003461.html
Rust “Struct Update Syntax” via `..` syntax in constructor
https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-insta…
## Alternatives
Without a copy-with-changes method, one must construct entirely new instances using the constructor. This can either be (a) fully spelled out as boilerplate code, or (b) use a symmetrical `#to_h` to feed the keyword-args constructor.
**(a) Boilerplate using constructor**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(x: Origin.x, y: Origin.y, **change)
```
**(b) Using a separately proposed `#to_h` method and constructor symmetry**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(**(Origin.to_h.merge(change)))
```
Notice that the above are not ergonomic -- leading so many of our peer language communities to adopt the `#with` method to copy an instance with discrete changes.
--
https://bugs.ruby-lang.org/
Issue #19099 has been updated by okuramasafumi (Masafumi OKURA).
I wonder if the code below is acceptable:
```ruby
class C
private_constant {
X = ...
}
end
```
Here, `private_constant` takes a block and every constant defined there are private. This is especially useful when defining multiple private constants at once.
----------------------------------------
Feature #19099: Support `private_constant` for an undefined constant
https://bugs.ruby-lang.org/issues/19099#change-100315
* Author: ujihisa (Tatsuhiro Ujihisa)
* Status: Open
* Priority: Normal
----------------------------------------
All the following discussion applies to `public_constant` too. Maybe `deprecate_constant` as well.
## Problem
```ruby
class C
X = ...
private_constant :X
end
```
The above idiom usually works fine, but when `...` part is long, like a 30-line Ruby Hash, it's very easy to miss the following `private_constant :X` part.
## Impossible solution
```ruby
class C
private_constant X = ...
end
```
Like `private`, if the above notation could work, it would be awesome, but it breaks so many backward compatibility. The constant assignment returns its value but not the name of the constant, and we should keep the current behaviour.
## Proposed solution
Allow the following new notation for `private_constant` by making constant private by name without actually resolving itself and raises an error.
``` ruby
class C
private_constant :X
X = ...
end
```
The current behaviour is to raise NameError.
```
/tmp/v8svpb4/95:2:in `private_constant': constant C::X1 not defined (NameError)
private_constant :X1
^^^^^^^^^^^^^^^^
from /tmp/v8svpb4/95:2:in `<class:C>'
from /tmp/v8svpb4/95:1:in `<main>'
```
This proposal breaks this backward compatibility.
Also I'm concerned about potential typos. It may be hard to find typos.
```ruby
class C
private_constant :BEHAVIOUR
BEHAVIOR = 123 # Remains public unintentionally
end
```
Maybe we need some sort of foolproof somewhere in this way.
--
https://bugs.ruby-lang.org/
Issue #12848 has been updated by byroot (Jean Boussier).
Status changed from Open to Rejected
Given the feature request I think we can just close it.
----------------------------------------
Feature #12848: Crazy idea: Allow regex definition for methods (Do not take it seriously please)
https://bugs.ruby-lang.org/issues/12848#change-100312
* Author: shevegen (Robert A. Heiler)
* Status: Rejected
* Priority: Normal
----------------------------------------
Me again, sorry - only crazy ideas coming about as of late here.
### Crazy idea: Allow regex definition for methods
I should wait until first april. :)
But anyway.
Consider this:
```ruby
def foo_bar
puts 'hi there!'
end; alias foobar foo_bar
```
Ok now we can call this either as:
```ruby
foo_bar()
foobar()
foo_bar
foobar
```
All things work!
Here I was wondering ... what if I can omit the alias part?
Tada! Enter regex-defined methods as idea!
```ruby
def foo_?bar
puts 'hi there!'
end
```
Now the above works too, without any alias. Yay!
I assume that this may not be possible perhaps syntax-wise - and
perhaps if it WOULD be possible, it should not be done anyway.
# It actually makes things harder to read, so I am also against this idea, too.
But!
It had to be published. :)
I think I remember once a collection of evil code in a file called
evil.rb. If I remember correctly, it may have been championed by
flori ... something. I even forgot the name. But it was pretty
fun. I don't remember if we could have shapechanging object but
I like the idea in itself (if we had that? I think you could
someone change the parent class ... somehow. Actually, this may
not be totally useless, I still think it may be a nice idea to
have things like a generic Button.new interface that gets
translated properly into the different GUI toolsets and also
for www code ... unify all the things!)
Things like that with evil.rb are sorta fun - experiment with evil
ideas that you should not use. There could be a whole type system
added in it as well! Mandatory type system - things that make you
unhappy when you use them. Since it is MANDATORY haha! :D
And then, on top of that, a ruby-to-crystal compiler just for the fun
of it (well, you write in ruby... and then just let it compile into
some binary via crystal ... without having to write crystal on your
own ... then you'd have the best of both worlds. Crystal feels heavier
on my brain than ruby but if it gives me faster binaries OR if I
can distribute code as a drop-out-exe for friends to use, this
would be good! My friends tend to be noobs so making things as
simple as possible is good. Also, I am much more a crystal noob
than a ruby noob though I am also a ruby noob too. So the crystal
idea, well, actually - would be nice if ruby itself would have
that too. Like scripting languages that can be compiled! And
run like on something like JVM just not needing java haha.)
It's Caturday sorta, don't mind me.
So actually, I think my second idea would be to have something
like evil.rb again, in stdlib/core or so. We have some `GOTO`
stuff too somewhere (I don't remember where ... it is probably
too evil to google for it... but I did ... the variable
`SUPPORT_JOKE`. We could also `SUPPORT_EVIL` yes! Or perhaps
`SUPPORT_FUN` or something like that.)
I don't remember if evil.rb was really used a lot by anyone
else, but perhaps it would be fun to toy with crazy evil
features - and you can not rely on them being made available
either, they may disappear or re-appear!
Anyway, don't take any of this too seriously please.
--
https://bugs.ruby-lang.org/
Issue #6047 has been updated by byroot (Jean Boussier).
I just tried my hand at this one: https://github.com/ruby/ruby/pull/6829
I think such a change would make sense. Not that `IO#read` without a size if common, but might as well do something sensible.
----------------------------------------
Feature #6047: read_all: Grow buffer exponentially in generic case
https://bugs.ruby-lang.org/issues/6047#change-100311
* Author: MartinBosslet (Martin Bosslet)
* Status: Open
* Priority: Normal
----------------------------------------
In the general case, read_all grows its buffer linearly by just the amount that is currently read from the underlying source. This results in a linear number of reallocs, It might turn out beneficial if the buffer were grown exponentially by multiplying with a constant factor (e.g. 1.5 or 2), thus resulting in only a logarithmic numver of reallocs.
I will provide a patch and benchmarks, but I'm already opening this issue so I won't forget.
See also https://bugs.ruby-lang.org/issues/5353 for more details.
--
https://bugs.ruby-lang.org/
Issue #19003 has been updated by hurricup (Alexandr Evstigneev).
This stays the same in the `preview3`. Are there any chances this will change until release?
Current behavior reduces usefulness and complicates usage of local tracepoints, because I can't just set smarter TP, but also I need to think about what fires when and in which cases we have chained events handling. This is really frustrating.
----------------------------------------
Bug #19003: TracePoint behavior inconsistency in 3.2.0-preview2
https://bugs.ruby-lang.org/issues/19003#change-100308
* Author: hurricup (Alexandr Evstigneev)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0preview2 (2022-09-09 master 35cfc9a3bb) [x86_64-linux]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
This is kind of continuation of my previous report about global/local TP processing (#18730).
Sample script:
```rb
def foo
return 1
end
puts RubyVM::InstructionSequence.of(method :foo).disasm
def step_over
TracePoint.new(:line, :return, :b_return) do |tp|
puts "Step over hits by #{tp.event} at #{tp.lineno}"
step_over
tp.disable
end.enable(target: RubyVM::InstructionSequence.of(method :foo), target_thread: Thread.current)
end
TracePoint.new(:line, :return, :b_return) do |tp|
if tp.lineno == 2
puts "Step into hits by #{tp.event} at #{tp.lineno}"
step_over
tp.disable
end
end.enable(target_thread: Thread.current)
a = foo
```
In ruby 3.1.2 we have expected behavior. Output:
```
== disasm: #<ISeq:foo@/home/hurricup/Projects/ruby-debugger/jb-debase-30/test_sample.rb:1 (1,0)-(3,3)> (catch: FALSE)
0000 putobject_INT2FIX_1_ ( 2)[LiCa]
0001 leave ( 3)[Re]
Step into hits by line at 2
Step over hits by return at 3
```
In ruby 3.2.0-preview2 - not so much. Output:
```
== disasm: #<ISeq:foo@/home/hurricup/Projects/ruby-debugger/jb-debase-30/test_sample.rb:1 (1,0)-(3,3)> (catch: false)
0000 putobject_INT2FIX_1_ ( 2)[LiCa]
0001 leave ( 3)[Re]
Step into hits by line at 2
Step over hits by line at 2
Step over hits by return at 3
```
--
https://bugs.ruby-lang.org/
Issue #19000 has been updated by mame (Yusuke Endoh).
@RubyBugs Please check my comment https://bugs.ruby-lang.org/issues/19000#note-13 . A wrong motivation example raises the suspicion that this API is actually confusing to users.
----------------------------------------
Feature #19000: Data: Add "Copy with changes method" [Follow-on to #16122 Data: simple immutable value object]
https://bugs.ruby-lang.org/issues/19000#change-100307
* Author: RubyBugs (A Nonymous)
* Status: Open
* Priority: Normal
----------------------------------------
*As requested: extracted a follow-up to #16122 Data: simple immutable value object from [this comment](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/109815)*
# Proposal: Add a "Copy with changes" method to Data
Assume the proposed `Data.define` exists.
Seeing examples from the [[Values gem]](https://github.com/ms-ati/Values):
```ruby
# A new class
Point = Data.def(:x, :y)
# An immutable instance
Origin = Point.with(x: 0, y: 0)
# Q: How do we make copies that change 1 or more values?
right = Origin.with(x: 1.0)
up = Origin.with(y: 1.0)
up_and_right = right.with(y: up.y)
# In loops
movements = [
{ x: +0.5 },
{ x: +0.5 },
{ y: -1.0 },
{ x: +0.5 },
]
# position = Point(x: 1.5, y: -1.0)
position = movements.inject(Origin) { |p, move| p.with(**move) }
```
## Proposed detail: Call this method: `#with`
```ruby
Money = Data.define(:amount, :currency)
account = Money.new(amount: 100, currency: 'USD')
transactions = [+10, -5, +15]
account = transactions.inject(account) { |a, t| a.with(amount: a.amount + t) }
#=> Money(amount: 120, currency: "USD")
```
## Why add this "Copy with changes" method to the Data simple immutable value class?
Called on an instance, it returns a new instance with only the provided parameters changed.
This API affordance is now **widely adopted across many languages** for its usefulness. Why is it so useful? Because copying immutable value object instances, with 1 or more discrete changes to specific fields, is the proper and ubiquitous pattern that takes the place of mutation when working with immutable value objects.
**Other languages**
C# Records: “immutable record structs — Non-destructive mutation” — is called `with { ... }`
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-t…
Scala Case Classes — is called `#copy`
https://docs.scala-lang.org/tour/case-classes.html
Java 14+ Records — Brian Goetz at Oracle is working on adding a with copy constructor inspired by C# above as we speak, likely to be called `#with`
https://mail.openjdk.org/pipermail/amber-spec-experts/2022-June/003461.html
Rust “Struct Update Syntax” via `..` syntax in constructor
https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-insta…
## Alternatives
Without a copy-with-changes method, one must construct entirely new instances using the constructor. This can either be (a) fully spelled out as boilerplate code, or (b) use a symmetrical `#to_h` to feed the keyword-args constructor.
**(a) Boilerplate using constructor**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(x: Origin.x, y: Origin.y, **change)
```
**(b) Using a separately proposed `#to_h` method and constructor symmetry**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(**(Origin.to_h.merge(change)))
```
Notice that the above are not ergonomic -- leading so many of our peer language communities to adopt the `#with` method to copy an instance with discrete changes.
--
https://bugs.ruby-lang.org/
Issue #13847 has been updated by hsbt (Hiroshi SHIBATA).
Assignee set to hsbt (Hiroshi SHIBATA)
----------------------------------------
Feature #13847: Gem activated problem for default gems
https://bugs.ruby-lang.org/issues/13847#change-100299
* Author: hsbt (Hiroshi SHIBATA)
* Status: Assigned
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
----------------------------------------
If you try to use some default gems with a fixed version using Bundler, there are cases where the current RubyGems/Bundler/Ruby specification can not be used with the version specified by the user.
For example
```
$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin17]
$ gem list | grep openssl
openssl (2.0.5, 2.0.4, default: 2.0.3)
```
In the environment such as ```require 'openssl'```, the version that is activated when openssl is searched with openssl is the version found first, ie 2.0.5.
```
$ ruby -ropenssl -e 'p OpenSSL::VERSION'
"2.0.5"
```
At this time, for example, suppose the user really wants to use openssl 2.0.4 and wrote the following Gemfile.
```
> cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem 'openssl', '2.0.4'
```
Unfortunately, since rubygems has required openssl before the bundler runs it will result in an activated error like this:
```
> bundle exec ruby -ropenssl -e 'p OpenSSL::VERSION'
/path/to/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/runtime.rb:317:in `check_for_activated_spec!': You have already activated openssl 2.0.5, but your Gemfile requires openssl 2.0.4. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
```
This problem can be avoided by bundling it as a vendoring library under bundler's repository if it is a default gem implemented with pure ruby.
Https://github.com/bundler/bundler/blob/master/lib/bundler/vendor/fileutils…
In the case of bundler, by separating the namespace as `Bundler::FileUtils`, even the version specified by the user is made available without conflict at the time of activate. However, this method can not be used with C extension library.
Since we want to use json/psych from the bundler team with rubygems/bundler to serialize data, we need about whether we can implement a way to avoid some kind of C extension on Ruby itself.
I discussed with @indirect who is maintainer of RubyGems/Bundler. We can resolve this problem like following feature of ruby.
```
require_for_bundler 'json', '2.0.2'
```
When we declared above `require_for_bundler`, We put a json-2.0.2 to placed in a namespace like `Bundler::JSON`. There were similar issues in the past as well.
https://bugs.ruby-lang.org/issues/10320
I think that the way of writing ```require 'json', version: '2.0.2', into: :Bundler``` which extended the method like this issue seems like that. Also, in this use case, it seems to be enough to use ```require 'json', version: :default, into: :Bundler``` which forces the use of default gem.
Matz, How do you think about this feature?
--
https://bugs.ruby-lang.org/