私は通常、「本能的」な方法で関数でプログラムを作成しますが、私の現在の問題はオブジェクトによって簡単に解決できるため、このメソッドを先に進めます。rebolにオブジェクトコンストラクタがあります
これを行うには、例えば、のinit()に相当するコンストラクタメソッドをオブジェクトに与える方法を見つけようとしています。
私はhttp://www.rebol.com/docs/core-fr/fr-index.htmlのドキュメントを見ましたが、関連するものは見つかりませんでした。
私は通常、「本能的」な方法で関数でプログラムを作成しますが、私の現在の問題はオブジェクトによって簡単に解決できるため、このメソッドを先に進めます。rebolにオブジェクトコンストラクタがあります
これを行うには、例えば、のinit()に相当するコンストラクタメソッドをオブジェクトに与える方法を見つけようとしています。
私はhttp://www.rebol.com/docs/core-fr/fr-index.htmlのドキュメントを見ましたが、関連するものは見つかりませんでした。
実は、(私は古き良きアドバイス続く:「フランスのマニュアルを読む」)を再びREBOLのコアのドキュメントを読むことによって、非常に簡単、コンストラクタを実装する別の方法があります:
http://www.rebol.com/docs/core-fr/fr-rebolcore-10.html#section-8
もちろんそれは英語のマニュアルでもある:
http://www.rebol.com/docs/core23/rebolcore-10.html#section-7
=>
自己変数を使用してのもう一つの例は、 自身のクローン機能である:
person: make object! [
name: days-old: none
new: func [name' birthday] [
make self [
name: name'
days-old: now/date - birthday
]
]
]
lulu: person/new "Lulu Ulu" 17-May-1980
print lulu/days-old
7366
私は、これは非常に便利見つけ、そしてこのように、コンストラクタはオブジェクト内にあります。この事実は、オブジェクトをより自立させる。
私は成功し、いくつかの地質学的なもののため、それがうまく機能が実装:
>> source orientation
orientation: make object! [
matrix: []
north_reference: "Nm"
plane_quadrant_dip: ""
new: func [{Constructor, builds an orientation object! based on a measurement, as given by GeolPDA device, a rotation matrix represented by a suite of 9 values} m][
make self [
foreach [a b c] m [append/only matrix to-block reduce [a b c]]
a: self/matrix/1/1
b: self/matrix/1/2
c: self/matrix/1/3
d: self/matrix/2/1
e: self/matrix/2/2
f: self/matrix/2/3
g: self/matrix/3/1
h: self/matrix/3/2
i: self/matrix/3/3
plane_normal_vector: reduce [matrix/1/3
matrix/2/3
matrix/3/3
]
axis_vector: reduce [self/matrix/1/2
self/matrix/2/2
self/matrix/3/2
]
plane_downdip_azimuth: azimuth_vector plane_normal_vector
plane_direction: plane_downdip_azimuth - 90
if (plane_direction < 0) [plane_direction: plane_direction - 180]
plane_dip: arccosine (plane_normal_vector/3)
case [
((plane_downdip_azimuth > 315) or (plane_downdip_azimuth <= 45)) [plane_quadrant_dip: "N"]
((plane_downdip_azimuth > 45) and (plane_downdip_azimuth <= 135)) [plane_quadrant_dip: "E"]
((plane_downdip_azimuth > 135) and (plane_downdip_azimuth <= 225)) [plane_quadrant_dip: "S"]
((plane_downdip_azimuth > 225) and (plane_downdip_azimuth <= 315)) [plane_quadrant_dip: "W"]
]
line_azimuth: azimuth_vector axis_vector
line_plunge: 90 - (arccosine (axis_vector/3))
]
]
repr: func [][
print rejoin ["Matrix: " tab self/matrix
newline
"Plane: " tab
north_reference to-string to-integer self/plane_direction "/" to-string to-integer self/plane_dip "/" self/plane_quadrant_dip
newline
"Line: " tab
rejoin [north_reference to-string to-integer self/line_azimuth "/" to-string to-integer self/line_plunge]
]
]
trace_te: func [diagram [object!]][
len_queue_t: 0.3
tmp: reduce [
plane_normal_vector/1/(square-root (((plane_normal_vector/1 ** 2) + (plane_normal_vector/2 ** 2))))
plane_normal_vector/2/(square-root (((plane_normal_vector/1 ** 2) + (plane_normal_vector/2 ** 2))))
]
O: [0 0]
A: reduce [- tmp/2
tmp/1
]
B: reduce [tmp/2 0 - tmp/1]
C: reduce [tmp/1 * len_queue_t
tmp/2 * len_queue_t
]
L: reduce [- axis_vector/1 0 - axis_vector/2]
append diagram/plot [pen black]
diagram/trace_line A B
diagram/trace_line O C
diagram/trace_line O L
]
]
>> o: orientation/new [0.375471 -0.866153 -0.32985 0.669867 0.499563 -0.549286 0.640547 -0.0147148 0.767778]
>> o/repr
Matrix: 0.375471 -0.866153 -0.32985 0.669867 0.499563 -0.549286 0.640547 -0.0147148 0.767778
Plane: Nm120/39/S
Line: Nm299/0
この方法のもう一つの利点は、(「新しい」方法で定義された変数は、直接オブジェクト「インスタンス」に属することです私はいくつかの問題に遭遇しました。他の方法では、自己/時には、変数を初期化する必要があるかどうかについて言及する必要があります)。
REBOLの中には特別なコンストラクタ関数はありませんが、あなたは仕様ブロック内のオブジェクトの作成時に、それを必要とする場合アドホック初期化コードを記述する可能性があります。たとえば:あなたはベースオブジェクトに慣例により、独自の「コンストラクタ」関数を定義するのであれば
a: context [x: 123]
b: make a [
y: x + 1
x: 0
]
、あなたは、作成上のスペックブロックを呼び出すことができます。渡された引数の可能な衝突を避けるだろう新の
a: context [
x: 123
init: func [n [integer!]][x: n]
]
new-a: func [n [integer!]][make a [init n]]
b: new-a 456
より堅牢な(しかし、少し長い)バージョン:あなたはそれを自動化したい場合は、このように、機能であることをラップすることができますオブジェクト自身の言葉でのinit に次のようになります。
new-a: func [n [integer!] /local obj][
also
obj: make a []
obj/init n
]
ます。また、最初の引数としてベースオブジェクトを取得し、自動的にCLON後コンストラクタバイ規則機能を呼び出します。より一般的な新しい機能を書くことができしかし、オプションのコンストラクタ引数を一般的な方法でサポートするのは、もっと難解です。
はREBOLののオブジェクトモデルはプロトタイプベース(Pythonや他のほとんどのOOP言語でクラスベースの対)であるので、「コンストラクタ」機能は、が作成された各新しいオブジェクトのを重複して取得することを覚えておいてください。膨大な数のオブジェクトを作成する場合は、このようなコストを避けたいかもしれません。
私の知る限り、init()
のようなオブジェクトコンストラクタを使用するための正式な方法/規約はありません。構築派生オブジェクトの組み込みの方法はもちろんあります:
make prototype [name: "Foo" description: "Bar"]
; where type? prototype = object!
私の最高の提案は、その後の方法、ここではそのような機能だと適用され、コンストラクタメソッドのオブジェクトを検査関数を定義するだろうと私[proposed previously VEの:
new: func [prototype [object!] args [block! none!]][
prototype: make prototype [
if in self 'new [
case [
function? :new [apply :new args]
block? :new [apply func [args] :new [args]]
]
]
]
]
使用は非常に簡単である:
thing: context [
name: description: none
new: [name: args/1 description: args/2]
]
derivative: new thing ["Foo" "Bar"]
012:プロトタイプオブジェクトは
new
値を有する場合、それは誘導体オブジェクトの構築に適用されます
このアプローチはRebol 2と3の両方で機能することに注意してください。
ok:必要な場合は、オブジェクト内のコンストラクタメソッドの適切な規則です。 – Pierre
私は、OOがどのようにREBOLで動作するかを調べようとしています。確かにプロトタイプです。
;---- First instance, created from its class ----;
this-object: THIS-CLASS/.new 1
print invoke this-object 'add [2]
;---- Second instance, created from from a prototype ----;
that-object: this-object/.class/.new 2
print invoke that-object 'add [4]
;---- Third instance, created from from a prototype in another way ----;
yonder-object: invoke that-object '.new [3]
print invoke yonder-object 'add [6]
;---- Fourth instance, created from from a prototype in a silly way ----;
silly-object: yonder-object/.class/.class/.class/.class/.new 4
print silly-object/.class/add 8 silly-object
print this-object/.class/add 8 silly-object
print THIS-CLASS/add 8 silly-object
(それはREBOL 2で動作し、そして:そして、あなたがこれを行うことができます
;---- Generic function for class or instance method invocation ----;
invoke: func [
obj [object!]
fun [word!]
args [block!]
][
fun: bind fun obj/.class
;---- Class method names start with a dot and instance method names don't:
unless "." = first to-string fun [args: join args obj]
apply get fun args
]
;---- A class definition ----;
THIS-CLASS: context [
.class: self ; the class refers to itself
;---- Class method: create new instance ----;
.new: func [x' [integer!] /local obj] [
obj: context [x: x' .class: none] ; this is the object definition
obj/.class: self/.class ; the object will refer to the class
; it belongs to
return obj
]
;---- An instance method (last argument must be the instance itself) ----;
add: func [y obj] [
return obj/x + y
]
]
:昨日、私は、機能の重複することなく、以下の古典的なオブジェクト指向のモデルを私に触発され、このページに出くわしました3,6,9,12,12,12を連続して印刷します。)オーバーヘッドはほとんどありません。多分他の解決策を見つけるのは難しくありません。正確にそれが本当の問題です:それを行うには余りにも多くの方法があります。 (たぶん、LoyalScriptのほうがいいかもしれません)
はい、どちらも非常に似た解決策になります。 initまたはnew?それはコンストラクタメソッドに名前を付けるための質問です... もちろん、大量のオブジェクトを生成する場合は、このようなメソッドは絶対に避けてください。私の現在の問題では、実際にいくつかのオブジェクトを考えていました。 – Pierre