Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip quesitonmark from query method in assignment #360

Open
jhass opened this issue Jan 28, 2015 · 4 comments
Open

Strip quesitonmark from query method in assignment #360

jhass opened this issue Jan 28, 2015 · 4 comments

Comments

@jhass
Copy link
Member

jhass commented Jan 28, 2015

This is a feature suggestion.

Suppose the following code:

obj.foo? = bar

This should actually call obj.foo=(bar) and not obj.foo?= (bar). Why? Because then you can write the following:

class A
  property! foo
end

a = A.new
a.foo? ||= bar

Whether this is accepted or not, I think we should disallow methods ending in ?=.

@asterite
Copy link
Member

This is interesting. Right now when you do:

hash[key] ||= value

it gets rewritten to:

hash[key]? || (hash[key] = value)

While when you do:

obj.property ||= value

it gets rewritten to:

obj.property || (obj.property = value)

There is a small inconsistency here, but the object implementing [] is most probably a Hash or a Hash-like object where you could get a nilable value (and Hash already has the []? method implemented), while for any object it's hard to know whether it's going to have property be nilable, raise, or there would be an alternative property? method.

So, we can leave things as they are and make:

obj.property? ||= value

be rewritten to:

obj.property? || (obj.property = value)

That way we cover all cases.

I'm not sure this is what you are suggesting. I would forbid writing obj.property? = value just by itself, but allow it when there's the ||= (or &&=).

To make it even more consistent, one would have to write hash[key]? ||= value, but I'm not really sure about this last thing.

@jhass
Copy link
Member Author

jhass commented Jan 28, 2015

It's sort of what I'm suggesting yes, I think it could be more intuitive by letting the compiler check whether there's obj.property? defined. When it is, rewrite to obj.property? || (object.property = value), if it's not defined rewrite to obj.property || (object.property = value). Then the same behavior could be used for Hash like calls too and they're no longer special cased.

@asterite
Copy link
Member

@jhass I think we can do that. But right now the syntax sugar is expanded by the parser, so we'd have to change that to expand it in the semantic phase. I don't see why we shouldn't do that: the smarter the compiler and the less the user has to choose what's the obvious correct way to do things, the better. Then we wouldn't even need that obj.property? ||= value syntax.

The only "issue" is if obj is a union type and there's a mixed behaviour. We'll have to think about that as well.

@straight-shoota
Copy link
Member

I don't think this should be driven by semantics. That would change the behaviour when a matching method is added in otherwise unrelated code.

I experienced this issue in combination with property! and I think the best solution would simply to expand obj.property? ||= value to obj.property? || (obj.property = value). There can't be a foo?= method anyway, so this would make perfectly sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants