呼び出されるオブジェクトを変更する関数/メソッドを説明するために使用される用語は何ですか?


12

一般的な質問で申し訳ありません。私はあちこち検索しましたが、これにたスレッドが非常に多く見つかりましたが、特定の質問に答えるスレッドはありません。おそらく、探している用語が存在しないためです。

私の友人はプログラミング、特にJavaScriptを学んでおり、なぜこれが機能しないのかと私に尋ねました。

var a = "Hello World";
a.replace("Hello", "Goodbye");

console.log(a)  // Logs "Hello World"

理由は、文字列はJavaSriptでは不変なreplaceので、変更しないためですa。それはBecuase 返す文字列を、あなたのような何かをする必要があると思い...

var a = "Hello World";
a = a.replace("Hello", "Goodbye");

console.log(a);  // Logs "Goodbye World"

ただし、代替はJavaScriptのような関数reverse()であり、それを呼び出すものをすべて変更します。例えば:

var fruits = ["Apples", "Oranges", "Bananas"];
fruits.reverse();

console.log(fruits)  // ["Bananas", "Oranges", "Apples"]

友人がなぜ機能してreplaceいないのかと私に尋ねると、私は知らない言葉に手を伸ばしていることに気付きました(私が知っている限り)...

「置換関数は________であるため、文字列を「string dot replace」に設定する必要があります。」

reverseは________であるため、「array dot reverse」に等しい配列を設定する必要はありません。

私はプロトタイプ関数に精通していますが、それが私が探している言葉だとは思いません。これらの空白を埋めるのを手伝ってくれる人はいますか?


6
たぶんその言葉は「ミューテーター」ですか?次のようにYou don't need to set an array equal to "array dot reverse", because reverse is a mutator function。私が考えて、私は専門用語がそれらを呼び出す「のmutate」のインスタンスという関数を参照すると聞きました。しかし、おそらくそれをどこかで再確認する必要があります。
FrustratedWithFormsDesigner

感謝します!ミューテーターメソッドについて読んだことがありますが、この会話に確実に適合すると思います。確かに私が探しているものの領域で。
サンティ

私は混乱しています:タイトルでは、それを呼び出したオブジェクトを変更する関数について尋ねますが、あなたの例では、それらが呼び出さたオブジェクトを変更するメソッド、つまりタイトルの正反対を示しています。2つのうちどちらですか?
ヨルグWミットタグ

確かに、これは30行の詳細で説明されています。ヘッズアップのおかげで、タイトルが正確になるように修正します!
サンティ

回答:


12

探している概念のペアは、可変/不変のパラメーターとインプレース/結果の返却です。

あなたの例では:

文字列を「string dot replace」に設定する必要があります。これは、replace関数 Pythonで不変の文字列を操作するため、replace関数新しい文字列を返すためです。

C / C ++プログラマーにとって、これは「参照渡し」ではなく「値渡し」パラメーターとしてより馴染みがあり、不変で結果を返します。

reverseはmutableである配列を操作するため、「array dot reverse」に等しい配列を設定する必要はありません。そのため、戻る前にインプレースで変更を加えることができます。

このようなC / Cなどの言語で++これは、アドレス通過すなわち「参照渡し」パラメータとして知られていることにより修飾されていない場合はconst変更する機能を可能にする、のmutate、そのアドレスの内容が結果を変えるインプレース戻る前に。

もちろん、両方のメカニズムによって返す結果は、例えば、その機能有することは珍しいことではないint SomeFn(int p1, int p2, int *ErrCode)、ことができ、潜在的に、戻り値および内容を変更することによって、両方の結果を返すをErrCode

第三の方法

完全を期すために、結果を返す3番目のメカニズムは、副作用またはグローバルによるものです。つまり、ファイルスコープ、プログラム全体、共有、または環境の値を変更します。これは一般的に悪いニュースと見なされます。非常によく文書化されていない限り、コードを注意深く読むことで何が変更されているかを知ることができるからです。C / C ++などの言語では、特定の名前の外部スコープ変数を、おそらく別のモジュールでも使用し、同じ名前のローカルスコープ変数をマスクしないことで、これは非常に簡単です。Pythonでは、外部スコープの値を読み取ることができますが、外部スコープの値が、global キーワード、外部スコープ変数を変更しようとすると、同じ名前のローカルが自動的に作成されます。


ああ、私はこれらの用語に精通していますが、関数自体を説明する実際の単語があるかどうかはわかりませんでした。たとえば、(The reverse function is a _______ function.)言われているように、これは私が友人に与えたものとほぼ同じ応答であるため、特定の用語があるかどうかはまだ疑問ですが、あなたの確認に感謝します。私は質問を少しの間開いたままにしておきますが、これらの言葉が単に存在しない場合の答えとしてこれを確かに受け入れます。
サンティ

2
Pythonなどの一部の言語では、自分自身を変更するクラスを使用することもできます。一部のコンテキストでは、この「モンキーパッチ」は多くの人にとって良いことと見なされ、「自己変更コード」と見なされて禁止されています。また、コードフラグメントがランダムに「変更」および/または結合された後、何らかの方法で「最高の」パフォーマンスを得るためにテストおよび選択される「進化型コード」を持つこともできます。
スティーブバーンズ

-1。文字列が可変であるか不変であるかは、文字列を操作している関数とは関係ありません。この関数は可変または不変ではなく、「戻り値またはインプレース」ではありません。関数は引数を変更しても戻ります。
マイルルーティング

@MilesRoutは、その場で修正する関数が引き続き戻り、明確にするためのC / C ++の例に加えて、完全性のための副作用による結果を追加した。
スティーブバーンズ

4

それを表現する私の好ましい方法は次のとおりです。

  • Array reverseメソッドは変化しています。それはミューテーターです。一般的な特殊なケースはセッターです。

  • String replaceメソッドは変化しません。それはだミューテータません何も変更しない場合、副作用はありません。一般的な特殊なケースはゲッターです。

  • JavaScript文字列は不変であるため、Stringメソッドは変更できません。

    "Hello World" .replace( "Hello"、 "Goodbye");

    あなたが不快になります。文字列リテラルは変更しません。結果を破棄します。静的コードアナライザーは、このようなバグを検出できる場合があります。

  • JavaScript配列は可変であるため、配列メソッドは変化する可能性があります。JavaScriptは、配列をローカルのストレージビンとして使用する傾向があり、簡単に変更され、まれにコピーされます。

2

時々、純粋な関数型プログラミングのコンテキストで使用されたとき、破壊的と呼ばれる入力値を変更する(したがって純粋な関数ではない)関数を聞いたことがあります。ただし、これが正しい用語かどうかはわかりません。

あなたの場合、あなたは言うでしょう:

replace関数は破壊的ではないため、文字列を「string dot replace」に設定する必要があります。

reverseは破壊的であるため、「array dot reverse」に等しい配列を設定する必要はありません。


1

おそらくあなたが探している言葉は純粋ですか?

replace()副作用(つまり、文字列の変更)がないように見えるので純粋ですが(reverse()配列の状態を変更するため不純です)。


関連する概念ですが、他のプロパティも意味します(たとえば、グローバル状態にアクセスせず、同じ入力に対して常に同じ出力を生成します)。
ジェイコブライレ

1

これらは通常、関数とメソッドに分けられます(メソッドは関数のサブセットです)。関数は、単独で呼び出すことができるコードのセクションですが、メソッドには、それが動作する現在の「コンテキスト」の概念があります。メソッドのアクションは、コンテキストの状態を変更します。

オブジェクト指向プログラミングでは、コンテキストは関数が動作しているインスタンスです。


0

公式の答えがあるかどうかはわかりませんが、ここに2つあります。

手順

あなたの質問によく似ているこの質問に対する良い答えのように思えたからです-あなたはそれをチェックアウトする必要があります。

インプレース単項演算

このページを確認してください:java.util.function。さまざまなプロトタイプのデリゲート(入力/出力シグニチャ)に一種の作り付けの名前を提供します。たとえば、引数を取り、何も返さないデリゲートはコンシューマと呼ばれます。

さて、OOPの賢明な学生として、メソッドは隠されたパラメーターthis)を受け取る関数にすぎないことに注意する必要があります。参照として提供されるため、入力パラメーターと出力パラメーターの両方として機能します。

これらのJavaの人(そして彼らはかなり賢いようです)によると、単一の入力を受け入れ、同じ型の値を返すデリゲートは、単項演算子と呼ばれます。

の場合array::Reverse()、配列は不変ではなく、潜在的に多くのスペースを占有する可能性があるため、その場で操作を実行する方が効率的で便利です。したがって、Reverse()あるインプレース単項演算子

しかし、私にとって、「演算子」とは、特別な記号(加算演算子、+またはとしても知られている)またはのような数学的なキーワードですmod。したがって、私はoperatのそれを呼び出すことを好むイオン得、その場で単項演算


あなたは概念を混ぜています。Reverse()オペレータがいない、単項演算子は、同じ型の値を返す必要はありません(例えば!deletetypeof)、および演算子は、デリゲートではありません。しかし、「インプレース」は、そのインスタンスを変更するメソッドの良い用語です。[私は投票しませんでしたが、すべての回答が有用であるにもかかわらず、誰かがすべての回答に投票したようです。]
Jerry101

あなたがフォローしているかどうかわかりません。任意のプロトタイプをデリゲートで表すことができます。「演算子」は(私が述べたように)私にとってはうまくいかないので、「操作」と言います。確かに、はいReverse()は単項操作です。しかし、全体的にこれは少し奇妙であることに同意しますが、リンクされたドキュメントの用語を逐語的に使用しています。少なくとも、何もないよりはましです。
ジョン・ウー

ああなるほど!ラムダをJavaに後付けするために、それらは機能インターフェース(1つのメソッドのみを備えたJavaインターフェース)のアイデアに基づいて構築されているため、通常のJavaオブジェクトを「関数」として適用することができます。(Brian Goetzはラムダの追加に関する技術講演を行っています。何度も「明らかなアプローチはダメだろう」と言っています。)ストリーム処理オブジェクトの機能インターフェイスを作成するとき、「演算子」などの用語を乱用しました。わかりにくいです!彼らは良い名前を使い果たしたに違いない。レシーバーオブジェクトを変更する/しないOOPメソッドの用語の良いソースではないと思います。
Jerry101
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.