I have read that modules (in this case ActiveSupport::Concern) in ruby are shared amongst all instances of the class initialised. So if that were true it would mean any instance variables would be shared among all of the instances in memory.
module SetPassword
extend ActiveSupport::Concern
attr_reader :password
def password=(new_password)
@password = new_password
self.crypted_password = password_digest(new_password, salt)
end
end
class User
include SetPassword
end
u = User.new; u.password = 'abcdef'
u2 = User.new; u2.password = '123456'
Is the code above safe to use? Or would the second user override the first user?
Module#include
is under the hood calling Module#append_features
. That means, nothing is shared and this might be easily checked (ActiveSupport::Concern
has nothing to do with the code you are to check.)
module SetPassword
attr_reader :password
def password=(new_password)
@password = new_password
puts <<~EOS
Setting password to: #{@password} (id: #{@password.__id__}).
Object: #{self.class.name} (#{self.__id__}).
Method: #{__callee__} on #{self.method(__callee__).__id__}.
EOS
end
end
class User
include SetPassword
end
u1 = User.new; u1.password = 'abcdef'
u2 = User.new; u2.password = '123456'
The code above demonstrates that everything (the password itself, the instance variable and even the method on it’s own) is different:
▶ u1 = User.new; u1.password = 'abcdef'
#⇒ Setting password to: abcdef (id: 46968741459360).
# Object: User (46968741459420).
# Method: password= on 46968741459040.
▶ u2 = User.new; u2.password = '123456'
#⇒ Setting password to: 123456 (id: 46968734231740).
# Object: User (46968734232020).
# Method: password= on 46968734230640.