Comments (27)
i'll take a stab at this tonight
from dry-types.
Want to mention that to_*
and Kernel
methods have different semantics, Integer()
will raise a TypeError
if coercion is not possible and to_i
will throw a NoMethodError
.
from dry-types.
One more thing:
i found workaround but it looks very ugly
What's ugly about it? It's not a workaround, it's the way of using this library :)
from dry-types.
@georgemillo that's why I suggested that Coercible
should be renamed to Kernel
or KernelCoercion
to make it more obvious.
It seems to me that the important thing about these Types is that they coerce, not that they coerce using a particular method
Actually, one of the biggest reasons why dry-types was created was to split coercion into different categories so that we can use dedicated coercion logic depending on the use case. That's why there's Coercible
(but as I mentioned I don't like that name), Form
and JSON
(and we'll add Params
for http params, and Form/JSON will reuse a lot from it). This way it's simpler and faster, and your code that uses dry-types is more intentional.
from dry-types.
In fact, the thing is that Ruby semantics are not very consistent... For example, Kernel#String()
will try to call first #to_str
and then #to_s
. Calling #to_s
is by no means an acceptable way to coerce a type to a string (for example, Object#to_s
).
My thought know is that the best thing to do would be to keep ruby semantics as an implementation detail (or expose them but not as the main API hierarchy) and to propose a consistent and rational type coercion system. That means adding Coercible::Symbol
, keeping Coercible::Bool
, changing Coercible::String
so that it just tries to call #to_str
or #to_s
in a whitelist of classes (like Integer
), and maybe something more.
Let me know what you decide and whether I can help in anything.
from dry-types.
This was already done last year, by me, oh well.
from dry-types.
@solnic Symbol
is put in NON_COERCIBLE
in this commit 761e759
Can you make it coercible again?
from dry-types.
I found workaround but it looks really ugly
Types::Strict::Symbol
.constructor(-> (val) { val.to_sym })
.enum(:a, :b, :c)
from dry-types.
@morr Coercible
uses coercion methods from Kernel
and there's no Kernel.Symbol
so we won't have coercible symbol. We could add coercible symbol to other types, like form or json.
from dry-types.
Because of the way of using it for strings :)
Types::Coercible::String('a', 'b', 'c')
vs
Types::Strict::Symbol
.constructor(-> (val) { val.to_sym })
.enum(:a, :b, :c)
from dry-types.
@morr you can just do this:
Types::Strict::Symbol.constructor(&:to_sym).enum(:a, :b, :c)
We can also think about adding a new type category for to_*
coercions, so we have Coerible
which uses Kernel
coercion functions, and we'd have another one that uses to_s
to_sym
to_i
and so on.
from dry-types.
Just wondering why it's so important that the Coercible
types are completely internally consistent in how they coerce a value? It seems to me that the important thing about these Types is that they coerce, not that they coerce using a particular method, and I don't see why users should be forced to think about subtle idiosyncrasies of Ruby itself (such as that there's a String()
and a Integer()
Kernel method but no Symbol()
) just to coerce a type. (It's also worth nothing that when it comes to strings for example, String()
is identical to to_s
anyway except in some very rare cases that are barely worth considering, so it's not like a second set of types that uses to_s
instead of String()
would really make a difference anyway.)
Similarly, Ruby has no class called Boolean
, only TrueClass
and FalseClass
. But we don't let this idiosyncrasy of Ruby stop us from adding a type called Bool
, since it's a common use case that users will expect to be covered. Types::Strict::Bool
is fundamentally different internally from the other types in the Strict
namespace, but it doesn't matter because users don't care about the internals, they just care that their type is a bool. Why not apply a similar logic to users who care about coercing input to a symbol?
from dry-types.
We can also think about adding a new type category for to_* coercions, so we have Coercrible which uses Kernel coercion functions, and we'd have another one that uses to_s to_sym to_i and so on.
@solnic @flash-gordon it seems it wasn't implemented. Could I take this one? If so, should we rename Coercible
to Kernel
? And which name do you like for #to_*
coercions?
from dry-types.
@waiting-for-dev first we need to decide IF we want to add this. I'm on the fence now, you'd rarely need it.
from dry-types.
@solnic I think you are right. There is nothing that right now you can't do and that the new namespace would allow you. It seems it would make the library more comprehensive, but, after a second thought, I would leave as it is unless we find better reasons.
The only reason I miss it from time to time is when I have to write:
Types::Strict::Symbol.constructor(&:to_sym)
Sure I'm too fussy, but I don't like seeing Strict
and :to_sym
in the same line (it confuses me at first sight because they sound incompatible) and I would like just to be able to do Types::Coercible::Symbol
, because it makes sense in my head, although I understand that it is a good thing to keep the semantics of the language. At the end, it is ruby's fault because there is no Kernel#Symbol() method
:) Maybe we could add a type constructor helper for, at least, make it shorter? Something like Types.ToSymbol()
from dry-types.
We could consider adding Params::Symbol
and JSON::Symbol
from dry-types.
Hmm, but sometimes you need it outside the scope of params and json coercions. I'm also using dry-types for non web development.
from dry-types.
Types::Strict::Bool is fundamentally different internally from the other types in the Strict namespace, but it doesn't matter because users don't care about the internals, they just care that their type is a bool. Why not apply a similar logic to users who care about coercing input to a symbol?
So, I'm actually having second thoughts about this. It is true that we diverged from Ruby's semantics with Bool
. I can also see how the lack of Coercible::Symbol
may surprise people.
I think I'm OK with adding it, after all. Just needed 3 years to reconsider 😆 I'll talk to other core devs about this.
from dry-types.
a consistent and rational type coercion system
I don't think this is a feasible thing :)
from dry-types.
a consistent and rational type coercion system
I don't think this is a feasible thing :)
I think you are right :D But maybe we can reach until a certain degree taking a very conservative approach.
I think I'm OK with adding it, after all. Just needed 3 years to reconsider laughing I'll talk to other core devs about this.
@solnic did you and dry-rb team conclude something definitive?
from dry-types.
@waiting-for-dev no, the focus was on other things
from dry-types.
Ok, sorry for the push, I just wanted to know in order to collaborate with the implementation. I'll wait, I understand this is no high priority right now.
from dry-types.
@timriley @flash-gordon are you OK with adding Coercible::Symbol
and moving away from the idea that Coercible
are only for coercions handled by Kernel
?
from dry-types.
I don't mind. I don't think adding a whole bunch of coercible types that use to_*
for coercions makes sense. It looks more reasonable to add what's missing to Coercible
instead.
from dry-types.
@solnic @flash-gordon I'm happy for us to add Coercible::Symbol
using #to_sym
under the hood.
I do think we should aim to keep the Coercible
family of types relatively small, but given the importance and wide use of symbols within typical Ruby programs, I think it needs to be in it.
from dry-types.
OK so we have an agreement 🤝 😄
from dry-types.
I re-opened this issue and update the description
from dry-types.
Related Issues (20)
- Constructor is not applied properly to the result of types Sum HOT 5
- Types::Params::Integer incorrect coercion for numeric values HOT 9
- Types::Params::*.optional not handling empty string HOT 4
- Anonymous Dry::Types based module cannot be extended HOT 4
- Params namespace disapearing HOT 9
- Params coercion for Array works in an unintuitive way HOT 1
- https://dry-rb.org/gems/dry-types/ not at latest version HOT 1
- [Security] Workflow ci.yml is using vulnerable action actions/checkout
- Compound Types with Examples HOT 1
- Dry::Container::Error: There is already an item registered with the key "nominal.string" on jruby-head HOT 4
- Future-proof local override for Types::Instance/Constructor classes that potentially collide with predicates
- Unexpected error raised from Sum type HOT 7
- Types::Coeercible::Integer, should this use Base 10? HOT 2
- Add Zeitwerk autoloader
- Using transform_keys breaks error handling
- Undefined method after upgrading dependencies. HOT 5
- Missing method implementation for `Enum.each_value` HOT 1
- Types.Constructor failing on Ruby 3.1 HOT 8
- A bug with array, struct and sum of structs in `try` method
- Fix BigDemical warning
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dry-types.