You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've put comments through numerous issues on this and it doesn't make sense to me to leave any of this discussion so scattered so I'm opening this issue to discuss the merits of designing the default behavior where ever AnyObject would return to be Result<AnyObject, AnyException>.
Pros
For anyone developing a Rust app and using Ruby from it then this would allow for “The Rust Way” of handling Ruby exceptions to be well written and used. As well as have the advantage of Rust's question mark syntax let val = some_result?;.
Cons
Implementing this behavior would require the majority of features to be run through Ruby's rb_protect which will catch exceptions and allows us to build the Result. This adds cost to the performance. When writing a Ruby program and using Rust to gain performance you don't necessarily want this added cost in performance as the major draw to use Rust in Ruby is all about performance.
probable re-write & major version change
Exceptions to the Rule
Some scenarios won't “ever” *cough* *cough* call for an exception to be raised like when doing equality checks. Equality checks simply make sense to return the bool type for convenience. Although any method that can be monkey-patched and rewritten may raise exceptions in which case that should use protect. The choice for design and usage would then come down to how strict to adhere to The Rust Way pattern in case of risk, or provide the end user more of a choice. My thoughts on this point is to be more relaxed on enforcing the return type and trust the developers to understand the risks and choose there own implementation decisions.
Alternatives
Looking at a Helix PR with_protect example gave me the idea to have an impl WithProtect on FnOnce() trait. It's just a rough idea but it would be something like lazily produce a FnOnce() closure and have that take &self for the method definition in the WithProtect trait to route the code through something like my protect_send method (#88). So we could do my_closure.with_protect() to run it.
Strictness
If the need for safety comes first and we choose a relaxed stance on enforcing Result return types then it would come down to where we choose to draw the line. Like, for example, when instantiating a new object both new and initialize methods are highly likely to raise an exception if the startup standards for that object are not met. However the alternative method allocate is nearly guaranteed to never do anything that would raise an exception so this would be one method not needing the Result return type.
Choosing a form of this as a relaxed standard will require a more case by case decision on implementing it. That would likely be the sole choice of the author of this project on his beliefs and weighting on the likeliness of any particular method to raise an exception.
My Stance
I'm not too picky about this change being implemented. With protect_send#88 and eval#79 developers should have enough to take the risk out of most scenarios. But this will require programmers to be more defensive and more on guard with their code when working with ruru. Perhaps the easiest solution would be the alternative I've proposed here above.
I leave this RFC here open for discussion.
The text was updated successfully, but these errors were encountered:
It's come to my attention upon further thinking on this subject that there is two contexts to deal with here. One is a Rust program taking advantage of Ruby and the other is a Ruby program taking advantage of Rust.
I believe there is a need for the Error kind which is currently in Rust/ruru for the Rust program side. But I do also believe we need an Exception/AnyException type for dealing with Ruby centric programs. In my minds eye I see this full implemented as AnyException being the core type used everywhere and the Error type as a wrapper to contain behavior on Rust side for Rust applications.
I've put comments through numerous issues on this and it doesn't make sense to me to leave any of this discussion so scattered so I'm opening this issue to discuss the merits of designing the default behavior where ever
AnyObject
would return to beResult<AnyObject, AnyException>
.Pros
let val = some_result?;
.Cons
rb_protect
which will catch exceptions and allows us to build theResult
. This adds cost to the performance. When writing a Ruby program and using Rust to gain performance you don't necessarily want this added cost in performance as the major draw to use Rust in Ruby is all about performance.Exceptions to the Rule
Some scenarios won't “ever” *cough* *cough* call for an exception to be raised like when doing equality checks. Equality checks simply make sense to return the
bool
type for convenience. Although any method that can be monkey-patched and rewritten may raise exceptions in which case that should useprotect
. The choice for design and usage would then come down to how strict to adhere to The Rust Way pattern in case of risk, or provide the end user more of a choice. My thoughts on this point is to be more relaxed on enforcing the return type and trust the developers to understand the risks and choose there own implementation decisions.Alternatives
Looking at a Helix PR
with_protect
example gave me the idea to have animpl WithProtect on FnOnce()
trait. It's just a rough idea but it would be something like lazily produce aFnOnce()
closure and have that take&self
for the method definition in the WithProtect trait to route the code through something like myprotect_send
method (#88). So we could domy_closure.with_protect()
to run it.Strictness
If the need for
safety
comes first and we choose a relaxed stance on enforcingResult
return types then it would come down to where we choose to draw the line. Like, for example, when instantiating a new object bothnew
andinitialize
methods are highly likely to raise an exception if the startup standards for that object are not met. However the alternative methodallocate
is nearly guaranteed to never do anything that would raise an exception so this would be one method not needing theResult
return type.Choosing a form of this as a relaxed standard will require a more case by case decision on implementing it. That would likely be the sole choice of the author of this project on his beliefs and weighting on the likeliness of any particular method to raise an exception.
My Stance
I'm not too picky about this change being implemented. With
protect_send
#88 andeval
#79 developers should have enough to take the risk out of most scenarios. But this will require programmers to be more defensive and more on guard with their code when working with ruru. Perhaps the easiest solution would be the alternative I've proposed here above.I leave this RFC here open for discussion.
The text was updated successfully, but these errors were encountered: