{{위키데이터 속성 추적}}
[[컴퓨터 과학]]에서 '''뮤테이터 메소드'''(mutator method)는 변수의 변경을 통제하기 위해 사용하는 [[메서드 (컴퓨터 프로그래밍)|메소드]]이다. '''세터'''(setter) 메소드로 널리 알려져 있다. 프라이빗 멤버 변수의 값을 반환하는 '''액세서'''(accessor)로도 불리는 게터(getter)와 동반하여 자주 사용된다.

뮤테이터 메소드는 [[캡슐화]]의 원칙을 유지하면서 [[객체 지향 프로그래밍]]에 주로 사용된다. 이 원칙에 따라 [[클래스 (컴퓨터 프로그래밍)|클래스]]의 멤버 [[변수 (컴퓨터 과학)|변수]]는 다른 코드로부터 숨겨져서 비공개되고 보호되며 원하는 새로운 값을 변수로 취하고 선택적으로 유효성을 확인하며 프라이빗 [[멤버 변수]]를 수정하는 퍼블릭 멤버 함수(뮤테이터 메소드)에 의해서만 수정이 가능하다. 뮤테이터 메소드는 할당 [[연산자 오버로딩]]과 비교되지만 이것들은 객체 계층의 레벨에서 차이가 있다.

뮤테이터 메소드는 객체 지향이 아닌 환경에서도 사용할 수 있다. 이 경우 수정할 변수의 [[포인터 (프로그래밍)|참조]]는 새로운 값과 함께 뮤테이터로 전달된다. 이 시나리오에서 컴파일러는 코드가 뮤테이터 메소드를 통과하여 변수를 직접 변경하는 일에 제한을 둘 수 없다. 이 제한을 두는 책임은 [[소프트웨어 개발|개발자]]에게 있으며 변수가 오직 뮤테이터 메소드를 통해서만 수정이 되고 직접 수정해서는 안 되도록 보장해야 한다.

뮤테이터 메소드를 지원하는 프로그래밍 언어에서 [[프로퍼티 (프로그래밍)|프로퍼티]]는 캡슐화 활용을 포기하지 않고도 편리한 대안을 제공한다.

== 예시 ==
=== 어셈블리어 ===
<syntaxhighlight lang="nasm">
student                   struct
    age         dd        ?
student                   ends
</syntaxhighlight>
<syntaxhighlight lang="nasm">
                     .code
student_get_age       proc      object:DWORD
                      mov       ebx, object
                      mov       eax, student.age[ebx]
                      ret
student_get_age       endp

student_set_age       proc      object:DWORD, age:DWORD
                      mov       ebx, object
                      mov       eax, age
                      mov       student.age[ebx], eax
                      ret
student_set_age       endp
</syntaxhighlight>
=== C ===
파일 student.h:
<syntaxhighlight lang="C">
#ifndef _STUDENT_H
#define _STUDENT_H

struct student; /* opaque structure */
typedef struct student student;

student *student_new(int age, char *name);
void student_delete(student *s);

void student_set_age(student *s, int age);
int student_get_age(student *s);
char *student_get_name(student *s);

#endif
</syntaxhighlight>

파일 student.c:
<syntaxhighlight lang="C">
#include <stdlib.h>
#include <string.h>
#include "student.h"

struct student {
  int age;
  char *name;
};

student *student_new(int age, char *name) {
  student *s = malloc(sizeof(student));
  s->name = strdup(name);
  s->age = age;
  return s;
}

void student_delete(student *s) {
  free(s->name);
  free(s);
}

void student_set_age(student *s, int age) {
  s->age = age;
}

int student_get_age(student *s) {
  return s->age;
}

char *student_get_name(student *s) {
  return s->name;
}
</syntaxhighlight>

파일 main.c:
<syntaxhighlight lang="C">
#include <stdio.h>
#include "student.h"

int main(void) {
  student *s = student_new(19, "Maurice");
  char *name = student_get_name(s);
  int old_age = student_get_age(s);
  printf("%s's old age = %i\n", name, old_age);
  student_set_age(s, 21);
  int new_age = student_get_age(s);
  printf("%s's new age = %i\n", name, new_age);
  student_delete(s);
  return 0;
}
</syntaxhighlight>

파일 Makefile:
<syntaxhighlight lang="makefile">
all: out.txt; cat $<
out.txt: main; ./$< > $@
main: main.o student.o
main.o student.o: student.h
clean: ;$(RM) *.o out.txt main
</syntaxhighlight>
=== C++ ===
파일 Student.h:
<syntaxhighlight lang="cpp">
#ifndef STUDENT_H
#define STUDENT_H

#include <string>

class Student {
public:
    Student(const std::string& name);

    const std::string& name() const;
    void name(const std::string& name);

private:
    std::string name_;
};

#endif
</syntaxhighlight>
파일 Student.cpp:
<syntaxhighlight lang="cpp">
#include "Student.h"

Student::Student(const std::string& name) : name_(name) {
}

const std::string& Student::name() const {
    return name_;
}

void Student::name(const std::string& name) {
    name_ = name;
}
</syntaxhighlight>

=== C# ===
초기 버전의 C 샤프:
<syntaxhighlight lang="csharp">
public class Student
{
    private string name;

    /// <summary>
    /// Gets or sets student's name
    /// </summary>
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}
</syntaxhighlight>

나중 버전의 C# (.NET Framework 3.5 이상):
<syntaxhighlight lang="csharp">
public class Student
{
    public string Name { get; set; }
}
</syntaxhighlight>

<syntaxhighlight lang="csharp">
public class Student
{
    public string Name { get; private set; }
}
</syntaxhighlight>

=== 커먼 리스프 ===
<syntaxhighlight lang="lisp">
(defclass student ()
  ((name      :initarg :name      :initform "" :accessor student-name) ; student-name is setf'able
   (birthdate :initarg :birthdate :initform 0  :reader student-birthdate)
   (number    :initarg :number    :initform 0  :reader student-number :writer set-student-number)))

;; Example of a calculated property getter (this is simply a method)
(defmethod student-age ((self student))
  (- (get-universal-time) (student-birthdate self)))

;; Example of direct slot access within a calculated property setter
(defmethod (setf student-age) (new-age (self student))
  (with-slots (birthdate) self
    (setf birthdate (- (get-universal-time) new-age))
    new-age))

;; The slot accessing options generate methods, thus allowing further method definitions
(defmethod set-student-number :before (new-number (self student))
  ;; You could also check if a student with the new-number already exists.
  (check-type new-number (integer 1 *)))
</syntaxhighlight>
=== D ===
<syntaxhighlight lang="d">
class Student {
    private char[] name_;
    // Getter
    @property char[] name() {
        return this.name_;
    }
    // Setter
    @property char[] name(char[] name_in) {
        return this.name_ = name_in;
    }
}
</syntaxhighlight>

<code>Student</code> 인스턴스는 아래와 같이 사용이 가능하다:
<syntaxhighlight lang="d">
auto student = new Student;
student.name = "David";           // same effect as student.name("David")
auto student_name = student.name; // same effect as student.name()
</syntaxhighlight>

=== 델파이 ===
<syntaxhighlight lang="delphi">
interface

type
  TStudent = class
  strict private
    FName: string;
    procedure SetName(const Value: string);
  public
    /// <summary>
    /// Get or set the name of the student.
    /// </summary>
    property Name: string read FName write SetName;
  end;

// ...

implementation

procedure TStudent.SetName(const Value: string);
begin
  FName := Value;
end;

end.
</syntaxhighlight>
=== 자바 ===
<syntaxhighlight lang="java">
public class Student {
    private String name;

    public String getName() {
        return name;
    }
    
    public void setName(String newName) {
        name = newName;
    }
}</syntaxhighlight>
=== 자바스크립트 ===
<syntaxhighlight lang="javascript">
function Student(name) {
  var _name = name;

  this.getName = function() {
    return _name;
  };

  this.setName = function(value) {
    _name = value;
  };
}
</syntaxhighlight>

<syntaxhighlight lang="javascript">
function Student(name){
    var _name = name;
   
    this.__defineGetter__('name', function() {
        return _name;
    });
   
    this.__defineSetter__('name', function(value) {
        _name = value;
    });
}
</syntaxhighlight>

<syntaxhighlight lang="javascript">
function Student(name){
    this._name = name;
}

Student.prototype = {
    get name() {
        return this._name;
    },
    set name(value) {
        this._name = value;
    }
};
</syntaxhighlight>

<syntaxhighlight lang="javascript">
var Student = {
    get name() {
        return this._name;
    },
    set name(value) {
        this._name = value;
    }
};
</syntaxhighlight>

<syntaxhighlight lang="javascript">
function Student(name){
    this._name = name;
}
Object.defineProperty(Student.prototype, 'name', {
    get: function() {
        return this._name;
    },
    set: function(value) {
        this._name = value;
    }
});
</syntaxhighlight>

=== 액션스크립트 3.0 ===
<syntaxhighlight lang="actionscript">
package
{
    public class Student
    {
        private var _name : String;
		
        public function get name() : String
        { 
            return _name;
        }

        public function set name(value : String) : void
        {
            _name = value;
        }
    }
}
</syntaxhighlight>

=== 오브젝티브C ===
전통적인 Objective-C 1.0 문법 사용:
<syntaxhighlight lang="objc">
@interface Student : NSObject
{
    NSString *_name;
}

- (NSString *)name;
- (void)setName:(NSString *)name;

@end

@implementation Student

- (NSString *)name
{
    return _name;
}

- (void)setName:(NSString *)name
{
    [_name release];
    _name = [name retain];
}

@end
</syntaxhighlight>

[[Mac OS X 10.6]], [[iOS 4]], [[Xcode]] 3.2에 사용되는 더 새로운 Objective-C 2.0 문법을 사용하여 위에 기술된 코드와 동일한 코드를 아래와 같이 생성할 수 있다:
<syntaxhighlight lang="objc">
@interface Student : NSObject

@property (nonatomic, retain) NSString *name;

@end

@implementation Student

@synthesize name = _name;

@end
</syntaxhighlight>

[[OS X 10.8]]과 [[iOS 6]]를 기점으로 [[Xcode]] 4.4 이상을 사용 시 문법을 단순화할 수 있다:
<syntaxhighlight lang="objc">
@interface Student : NSObject

@property (nonatomic, strong) NSString *name;

@end

@implementation Student

//Nothing goes here and it's OK.

@end
</syntaxhighlight>

=== 펄 ===
<syntaxhighlight lang="perl">
package Student;

sub new {
    bless {}, shift;
}

sub set_name {
    my $self = shift;
    $self->{name} = $_[0];
}

sub get_name {
    my $self = shift;
    return $self->{name};
}

1;
</syntaxhighlight>

<syntaxhighlight lang="perl">
package Student;
use base qw(Class::Accessor);
__PACKAGE__->follow_best_practice;

Student->mk_accessors(qw(name));

1;
</syntaxhighlight>

<syntaxhighlight lang="perl">
package Student;
use Moose;

# Moose uses the attribute name as the setter and getter, the reader and writer properties
# allow us to override that and provide our own names, in this case get_name and set_name
has 'name' => (is => 'rw', isa => 'Str', reader => 'get_name', writer => 'set_name');

1;
</syntaxhighlight>
=== PHP ===
<syntaxhighlight lang="php">
class Student
{
    private string $name;

    /**
     * @return string The name.
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @param string $newName The name to set.
     */
    public function setName(string $newName): void
    {
        $this->name = $newName;
    }
}</syntaxhighlight>
<syntaxhighlight lang="python">
class Student:
    # Initializer
    def __init__(self, name: str) -> None:
        # An instance variable to hold the student's name
        self._name = name

    # Getter method
    @property
    def name(self):
        return self._name

    # Setter method
    @name.setter
    def name(self, new_name):
        self._name = new_name
</syntaxhighlight>
<syntaxhighlight lang="pycon">
>>> bob = Student("Bob")
>>> bob.name 
Bob
>>> bob.name = "Alice"
>>> bob.name 
Alice
>>> bob._name = "Charlie" # bypass the setter
>>> bob._name # bypass the getter
Charlie
</syntaxhighlight>
=== 래킷 ===
<syntaxhighlight lang="racket">
#lang racket
(define student%
  (class object%
    (init-field name)
    (define/public (get-name) name)
    (define/public (set-name! new-name) (set! name new-name))
    (super-new)))

(define s (new student% [name "Alice"]))
(send s get-name)                       ; => "Alice"
(send s set-name! "Bob")
(send s get-name)                       ; => "Bob"
</syntaxhighlight>

<syntaxhighlight lang="racket">
#lang racket
(struct student (name) #:mutable)
(define s (student "Alice"))
(set-student-name! s "Bob")
(student-name s)                        ; => "Bob"
</syntaxhighlight>

=== 루비 ===
개개의 액세서와 뮤테이터 메소드를 정의하면 데이터의 전처리 또는 유효성 확인을 위한 공간을 만들어준다.
<syntaxhighlight lang="ruby">
class Student
  def name
    @name
  end

  def name=(value)
    @name=value
  end
end
</syntaxhighlight>

<code>@name</code> 변수의 읽기 전용 단순 공개 접근:
<syntaxhighlight lang="ruby">
class Student
  attr_reader :name
end
</syntaxhighlight>

<code>@name</code> 변수의 읽기-쓰기 단순 공개 접근:
<syntaxhighlight lang="ruby">
class Student
  attr_accessor :name
end
</syntaxhighlight>

=== 러스트 ===
<syntaxhighlight lang="rust">
struct Student {
    name: String,
}

impl Student {
    fn name(&self) -> &String {
        &self.name
    }

    fn set_name(&mut self, name: String) {
        self.name = name
    }
}
</syntaxhighlight>

=== 스몰토크 ===
<syntaxhighlight lang="smalltalk">
  age: aNumber
     " Set the receiver age to be aNumber if is greater than 0 and less than 150 "
    (aNumber between: 0 and: 150)
       ifTrue: [ age := aNumber ]
</syntaxhighlight>

=== 비주얼 베이직 닷넷 ===
기본 코드:
<syntaxhighlight lang="vb">

Public Class Student

    Private _name As String

    Public Property Name()
        Get
            Return _name
        End Get
        Set(ByVal value)
            _name = value
        End Set
    End Property

End Class

</syntaxhighlight>

VB.NET 2010 코드:
<syntaxhighlight lang="vb">

Public Class Student
    Public Property name As String
End Class

</syntaxhighlight>

== 같이 보기 ==
* [[프로퍼티 (프로그래밍)]]
* [[인덱서 (프로그래밍)]]
* [[불변객체]]

[[분류:메소드 (컴퓨터 프로그래밍)]]