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

Unexpected behavior with trait arguments #7

Closed
codener opened this issue Jan 11, 2022 · 1 comment
Closed

Unexpected behavior with trait arguments #7

codener opened this issue Jan 11, 2022 · 1 comment

Comments

@codener
Copy link
Member

codener commented Jan 11, 2022

In a trait, I have a method that is using one of the trait arguments. In case the argument is not given, it falls back to a default value.

The unexpected: as soon as the default value is generated, it is stored at trait level and gets returned on each invocation. In other words, the default value is only evaluated once. In many cases, this will be no problem. However, the issue arises with a dynamic default value. See (and try) this Ruby script, where the default value is derived from the class name:

require 'modularity'

module DoesDemo
  as_trait do |name: nil|
  
    define_method :demo do
      name ||= self.class.name
      puts name
    end
    
  end
end

class Base
  include DoesDemo
end

class One < Base
end

class Two < Base
end

One.new.demo # => One
Two.new.demo # => One # wrong

As you can see, the return value of any subclass's demo method is the name of the first-defined class. (It would be the same with name ||= Time.now: the defaulted timestamp is instantiated once and returned on each invocation of demo.)

The distilled issue seems to be that assigning variables named like trait arguments will change state at trait level, i.e. modify the trait argument value.

Expected behavior

demo would always return the name of the current class (or the current time). Assigning a variable named like a trait argument should not change the value of the trait argument.

Workaround

Avoiding to assign variables named like any of the trait arguments.


I am not sure whether this behavior is a real bug, or if it might be a feature of define_method. Anyway, a solution that enables to ||=-assign variables named like trait arguments would be appreciated.

@triskweline
Copy link
Member

This is how variable scopes work in Ruby. There is nothing we can change here.

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

No branches or pull requests

3 participants