.. index::
	single: 関数とメソッドのスコープ規則; はじめに

============================
関数とメソッドのスコープ規則
============================

関数とメソッドのスコープ規則を学びます。

この情報は Ring で大規模アプリケーションの開発をはじめるときに重要です。

下記はアプリケーションに存在・使用されています。

* Ring で記述された数多のパッケージとクラス
* Ring で記述された数多の関数
* Ring 標準関数 (C 言語で記述)
* C/C++ で記述された関数とクラス

.. index::
	pair: 関数とメソッドのスコープ規則; Ring が関数とメソッドを見つける方法は？

Ring が関数とメソッドを見つける方法は？
=======================================

メソッドまたは関数を呼び出し時に関数の検索処理を開始します。

見つかった   --> 関数の呼び出しを行い、別の検索で再利用できるようにするために
Ring は関数ポインタをキャッシュへ格納します。

見つからない --> ランタイムエラーメッセージ (Try/Catch で回避できます)

検索の処理内容と方法は？

この順に従って関数やメソッドの検索が行われます。

1 - メソッドの検索 (クラスの内側にあるメソッドまたは括弧 { } を使用したオブジェクトの場合)

2 - プログラマが Ring コードで記述した関数の検索

3 - Ring 標準関数など C/C++ で記述された関数の検索

これでクラスメソッドのコードが綺麗になり、関数の名前衝突を全て回避できるようになります。

クラスにあるメソッドと同じ名前の関数を呼び出したい場合はラッパー関数が必要になるか、
または { } を使用した一時作業用のオブジェクトへのアクセス後に関数を呼び出します。

C/C++ の関数を Ring の関数へ置き換えることができます。

Ring の関数を Ring のメソッドへ置き換えることができます。


.. note:: いかなる場合であろうも self.メソッド() の使用は必要ありません。

.. tip:: this.メソッド() は、括弧 { } でアクセスすると現在の有効なスコープから除外できます。さらにクラス内メソッドの呼び出しにも使えます。

.. index::
	pair: 関数とメソッドのスコープ規則; 関数とメソッドの間で名前を共有する方法の用例

関数とメソッドの間で名前を共有する方法の用例
============================================

この用例を参照してください。

.. code-block:: ring

	func main
		o1 = new myclass { test() test2() }
		test2()

	func f1
		see "f1 function" + nl

	func f2 
		see "f2 function" + nl

	func f3 
		see "f3 function" + nl

	func test2
		myline()
		see "test2 function" + nl
		new myclass {
			f1()
			f2()
			f3()
			self.f3()
		}	
		myobj = new myclass
		myobj.f3()
		myline()

	func myline
		see copy("=",40) + nl

	Class myclass

		func test
			myline()
			see "test method" + nl
			f1()
			f2()
			f3()
			myline()

		func f3
			see "f3 method" + nl

		func test2
			myline()
			see "test2 method" + nl
			self {
				f1()
				f2()
				f3()
			}
			myline()



実行結果:

.. code-block:: none

	========================================
	test method
	f1 function
	f2 function
	f3 method
	========================================
	========================================
	test2 method
	f1 function
	f2 function
	f3 method
	========================================
	========================================
	test2 function
	f1 function
	f2 function
	f3 method
	f3 method
	f3 method
	========================================

.. index::
	pair: 関数とメソッドのスコープ規則; 現在のクラスで名前を共有する関数とメソッドを呼び出すには

現在のクラスで名前を共有する関数とメソッドを呼び出すには
========================================================

前述の用例では f3() 関数と f3() メソッドがあります。

どうすれば test() メソッドから f3() 関数を呼び出せますか？

解決方法 (1) : 現在のオブジェクトのスコープを別のオブジェクトのスコープへ変更します。

この解決方法では、現在のオブジェクトのスコープの変更で使用するために、ローカルで呼び出される空のクラスがあります。

.. code-block:: ring

	func main
		o1 = new myclass { test()}

	func f1
		see "f1 function" + nl

	func f2 
		see "f2 function" + nl

	func f3 
		see "f3 function" + nl

	func myline
		see copy("=",40) + nl

	Class myclass

		func test
			myline()
			see "test method" + nl
			f1()
			f2()
			f3()		   # f3() メソッドの呼び出し
			new local { f3() } # f3() 関数の呼び出し
			myline()

		func f3
			see "f3 method" + nl

	class local

実行結果:

.. code-block:: none

	========================================
	test method
	f1 function
	f2 function
	f3 method
	f3 function
	========================================

