Skip to content

Why does this feature exist? And how does one deal with optionals for methods already ending with a question mark? #2

@jordaaash

Description

@jordaaash

The benefits of ActiveSupport's use of #try with a symbol for handling this feature are many.

First and foremost, there is already a very well-established Ruby convention for question mark methods, which are methods that (usually) take no arguments, return a boolean value, and are usually idempotent -- they don't change anything about the object's state when called, they only report it. This is in fact so common it's baked into basic objects for methods like #nil?, #empty?, and many, many others, as well as countless libraries that already use the convention.

By ignoring this convention, swift-ruby creates ambiguity for a questionable benefit that is already handled quite elegantly by #try, and it does so in a way that prevents its use in obvious special cases.

When I call #active? on my object, am I perhaps checking the state of active (idempotent) or am I actually calling active on the object, perhaps changing the state (not idempotent) of the object?

Let's assume (as swift-ruby does) that it's the latter. Even if I choose to make this assumption for my object, since I can't predict what classes may subclass said object, how can I know someone won't implement an #active? method for checking it's "active" state later, thereby breaking any code (including external code) that used swift-ruby's active? to call it?

Preventing this kind of ambiguity is what conventions are for. Ignoring the fact that it's pretty reckless to override #method_missing on Object in code intended for a library or language feature, and the performance issues that arise from that choice, it's not only unclear what you're doing when you call #foo?, but it can't even be relied upon to work in all cases.

To illustrate, let's further assume that I actually do have another declared method on my object, #foo? If I wanted to call this object with swift-ruby if it exists and ignore it otherwise (like I would with object.try(:foo?), I can't do that because in swift-ruby, that construct is object.foo?? which is not valid syntax and will presumably error.

When I see code like object.try(:foo?) and active?, it's quite apparent from reading what the developer intended. If you intend to port Swift features to Ruby, features that are basically just syntactical sugar, I think it should be done with more regard for the nature of the Ruby language and its conventions.

Ruby already has elegant solutions to problems that Swift's Optionals purport to solve, such as default values when setting a variable (using ||= for example), and especially the #try feature in question. This feature being proposed creates obvious new problems without having any clear benefit. I don't doubt that Swift will be much more pleasant to code in that Objective C, but that doesn't mean that Ruby has imminent need of borrowing its language constructs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions