කුමක්ද කරන්නේ class << self
කරන්න රූබි ?
කුමක්ද කරන්නේ class << self
කරන්න රූබි ?
Answers:
පළමුව, class << foo
සින්ටැක්ස් foo
සිංගල්ටන් පංතිය (අයිජන් ක්ලාස්) විවෘත කරයි . මෙම නිශ්චිත වස්තුව මත කැඳවන ක්රම වල හැසිරීම විශේෂීකරණය කිරීමට මෙය ඔබට ඉඩ සලසයි.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
දැන්, ප්රශ්නයට පිළිතුරු සැපයීම සඳහා: වත්මන් වස්තුව සඳහා ක්රම නැවත අර්ථ දැක්විය හැකි වන පරිදි ( සිංගල්ටන් පන්තිය class << self
විවෘත කරයි) (පන්තියක් හෝ මොඩියුලයක් තුළ පන්තිය හෝ මොඩියුලයම වේ ). සාමාන්යයෙන්, මෙය පන්ති / මොඩියුල ("ස්ථිතික") ක්රම නිර්වචනය කිරීමට භාවිතා කරයි:self
self
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
මෙය කෙටියෙන් ද ලිවිය හැකිය:
class String
def self.value_of obj
obj.to_s
end
end
හෝ ඊටත් වඩා කෙටි:
def String.value_of obj
obj.to_s
end
ශ්රිත අර්ථ දැක්වීමක් තුළ ඇති විට, ශ්රිතය self
කැඳවනු ලබන වස්තුවට යොමු වේ. මෙම අවස්ථාවේදී, class << self
එම වස්තුව සඳහා සිංගල්ටන් පන්තිය විවෘත කරයි; එහි එක් භාවිතයක් වන්නේ දුප්පතාගේ රාජ්ය යන්ත්රය ක්රියාත්මක කිරීමයි.
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
එබැවින්, ඉහත උදාහරණයේ දී, සෑම අවස්ථාවක්ම වෙනස් StateMachineExample
වී process_hook
ඇත process_state_1
, නමුත් දෙවැන්නෙහි එය නැවත අර්ථ දැක්විය හැක්කේ කෙසේදැයි බලන්න process_hook
( self
වෙනත් StateMachineExample
අවස්ථාවන්ට පමණක් බලපාන්නේ නැත ) process_state_2
. එබැවින්, ඇමතුම්කරුවෙකු process
ක්රමයට කතා කරන සෑම අවස්ථාවකම (එය නැවත අර්ථ දැක්විය හැකි යැයි කියනු ලැබේ process_hook
), හැසිරීම වෙනස් වන්නේ එය කුමන තත්වයකද යන්න මතය.
class << self
පංති / මොඩියුල ක්රම නිර්මාණය කිරීම සඳහා එය වඩාත් පොදු භාවිතයකි . මම බොහෝ විට එම භාවිතය පුළුල් කරමි class << self
, මන්ද එය වඩාත් මුග්ධ භාවිතයකි.
a
' වෙත යොමු කිරීම ඇත්තෙන්ම ව්යාකූල ය . එය සිංගල්ටන් පන්තිය වෙනස් කරන්නේ නම් එය අනෙක් සියලුම අවස්ථාවන්ට බලපායි . දේ තවමත් අමානුෂික තියෙන්නේ ඔබට පසුව නැවත විවෘත වන්නේ නැති බව දක්වන ලෙසට එවකට තවමත් නව වෙනස්කම් ගන්න වනු ඇත. singleton_class
a
inspect
String
String
String
String
inspect
a
class << self
වටිනාකම වඩා නපුරු දෙයක් self
, වාරණ ගේ විෂය පථය තුල කටය පන්ති සමාන සකස්?
මම මේ ගැන සුපිරි සරල පැහැදිලි කිරීමක් සොයා class << self
, Eigenclass
සහ ක්රම විවිධ වර්ගයේ.
රූබි හි, පන්තියකට යෙදිය හැකි ක්රම තුනක් තිබේ:
උදාහරණ ක්රම සහ පන්ති ක්රම වෙනත් ක්රමලේඛන භාෂාවල ඒවායේ සමජාතීයතාවයට බොහෝ දුරට සමාන ය.
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
Eigenclass
(සිංගල්ටන් ක්රම ඇතුළත්) වෙත ප්රවේශ විය හැකි තවත් ක්රමයක් වන්නේ පහත දැක්වෙන වාක්ය ඛණ්ඩයයි class <<
:
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
මෙම සන්දර්භය තුළ self
පන්තියම වන සිංගල්ටන් ක්රමයක් දැන් ඔබට අර්ථ දැක්විය හැකිය Foo
:
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
foo.singleton_class.instance_methods(false)
පරීක්ෂා කිරීමට භාවිතා කළ හැකිය .
සාමාන්යයෙන් නිදර්ශන ක්රම ගෝලීය ක්රම වේ. එයින් අදහස් කරන්නේ ඒවා අර්ථ දක්වා ඇති පන්තියේ සෑම අවස්ථාවකම ඒවා ලබා ගත හැකි බවයි. ඊට වෙනස්ව, තනි වස්තුවක් මත සිංගල්ටන් ක්රමයක් ක්රියාත්මක වේ.
පන්තිවල රූබි ගබඩා කිරීමේ ක්රම සහ සියලුම ක්රම පන්තියක් සමඟ සම්බන්ධ විය යුතුය. සිංගල්ටන් ක්රමයක් නිර්වචනය කරන වස්තුව පන්තියක් නොවේ (එය පන්තියක නිදසුනකි). පංතිවලට පමණක් ක්රම ගබඩා කළ හැකි නම්, වස්තුවකට සිංගල්ටන් ක්රමයක් ගබඩා කරන්නේ කෙසේද? සිංගල්ටන් ක්රමයක් නිර්මාණය කළ විට, රූබි ස්වයංක්රීයව එම ක්රමය ගබඩා කිරීම සඳහා නිර්නාමික පන්තියක් නිර්මාණය කරයි. මෙම නිර්නාමික පංති මෙටාක්ලාස් ලෙස හැඳින්වේ, එය සිංගල්ටන් පංති හෝ අයිජන් ක්ලාස් ලෙසද හැඳින්වේ. සිංගල්ටන් ක්රමය මෙටාක්ලාස් සමඟ සම්බන්ධ වන අතර අනෙක් අතට සිංගල්ටන් ක්රමය අර්ථ දක්වා ඇති වස්තුව සමඟ සම්බන්ධ වේ.
තනි වස්තුවක් තුළ බහු සිංගල්ටන් ක්රම නිර්වචනය කර ඇත්නම්, ඒවා සියල්ලම එකම මෙටාක්ලාස් තුළ ගබඩා වේ.
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
ඉහත උදාහරණයේ දී, පංතිය << z1 වත්මන් ආත්මය z1 වස්තුවෙහි මෙටාක්ලාස් වෙත යොමු කරයි. ඉන්පසු එය මෙටාක්ලාස් තුළ ඇති say_hello ක්රමය අර්ථ දක්වයි.
පංති යනු වස්තූන් ද වේ. පන්ති ක්රම යනු පන්ති වස්තුවක් හා සම්බන්ධ සිංගල්ටන් ක්රමවලට වඩා වැඩි දෙයක් නොවේ.
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
සියලුම වස්තූන්හි මෙටාක්ලාස් තිබිය හැක. ඒ කියන්නේ පන්තිවලට මෙටාක්ලාස් ද තිබිය හැකිය. ඉහත උදාහරණයේ දී, පංතිය << ස්වයං ස්වයං වෙනස් කිරීම නිසා එය සැබුටන් පන්තියේ මෙටාක්ලාස් වෙත යොමු කරයි. පැහැදිලි ග්රාහකයක් නොමැතිව ක්රමයක් නිර්වචනය කළ විට (ක්රමය නිර්වචනය කරනු ලබන පන්තිය / වස්තුව), එය වත්මන් විෂය පථය තුළ ව්යංගයෙන් අර්ථ දැක්වේ, එනම් ස්වයං අගය. එබැවින්, සැබුටන් පන්තියේ මෙටාක්ලාස් තුළ දේවල් ක්රමය අර්ථ දක්වා ඇත. ඉහත උදාහරණය පන්ති ක්රමයක් අර්ථ දැක්වීමට තවත් ක්රමයක් පමණි. IMHO, පන්ති ක්රම නිර්වචනය කිරීම සඳහා def self.my_new_clas_method සින්ටැක්ස් භාවිතා කිරීම වඩා හොඳය, එය කේතය තේරුම් ගැනීමට පහසු කරයි. ඉහත උදාහරණය ඇතුළත් කර ඇති නිසා පන්තිය << ස්වයං වාක්ය ඛණ්ඩය හරහා පැමිණෙන විට සිදුවන්නේ කුමක්ද යන්න අපට වැටහේ.
රූබි පංති පිළිබඳ අමතර තොරතුරු මෙම ලිපියෙන් සොයාගත හැකිය .
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[එය එහි වාරණයේ self == thing.singleton_class
සන්දර්භය තුළ කරයි] .
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi
වස්තුව උරුම වන්නේ එහි #methods
සිට #singleton_class.instance_methods
පසුව ය #class.instance_methods
.
මෙන්න අපි දුන්නා hi
ගේ කටය පන්ති උදාහරණයක් ක්රමය :a
. පංතිය << හායි වෙනුවට එය කළ හැකිව තිබුණි .
hi
ගේ #singleton_class
සියලු උදාහරණයක් ක්රම ඇත hi
s '' #class
(සමහර වැඩි විය හැකි ඇති අතර, :a
මෙහි).
[උදාහරණ ලෙස දේවල් ක්රම #class
සහ #singleton_class
ඒවා කෙලින්ම යෙදිය හැකිය. රූබි විසින් දෙයක් දකින විට, එය මුලින්ම සොයන්නේ: thing.singleton_class.instance_methods හි ක්රම නිර්වචනයක් සහ පසුව thing.class.instance_methods]
මාර්ගය වන විට - ඔවුන් වස්තුව ගේ කතා කටය පන්ති == metaclass == eigenclass .
А සිංගල්ටන් ක්රමය යනු තනි වස්තුවකට පමණක් අර්ථ දක්වා ඇති ක්රමයකි.
උදාහරණයක්:
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
සොම් ක්ලාස් හි සිංගල්ටන්ගේ ක්රම
පරීක්ෂණය
Test_obj හි සිංගල්ටන්ගේ ක්රම
test_2
test_3
ඇත්ත වශයෙන්ම ඔබ ඔබේ රූබි ව්යාපෘති සඳහා සී දිගුවන් ලියන්නේ නම් මොඩියුල ක්රමයක් නිර්වචනය කිරීමට ඇත්තේ එක් මාර්ගයක් පමණි.
rb_define_singleton_method
මෙම ස්වයං ව්යාපාරය වෙනත් සියලු ආකාරයේ ප්රශ්න විවෘත කරන බව මම දනිමි, එවිට ඔබට එක් එක් කොටස සෙවීමෙන් වඩා හොඳ කළ හැකිය.
වස්තු පළමුව.
foo = Object.new
මට foo සඳහා ක්රමයක් කළ හැකිද?
ෂුවර්
def foo.hello
'hello'
end
මා එය කරන්නේ කුමක් ද?
foo.hello
==>"hello"
තවත් වස්තුවක් පමණි.
foo.methods
ඔබට සියලු වස්තු ක්රම සහ ඔබේ නව ක්රමය ලැබේ.
def foo.self
self
end
foo.self
යන්තම් foo Object.
පංතිය සහ මොඩියුලය වැනි වෙනත් වස්තූන්ගෙන් ඔබ මෝඩයින් කළහොත් කුමක් සිදුවේදැයි බැලීමට උත්සාහ කරන්න. සියලු පිළිතුරු වලින් නිදසුන් සමඟ සෙල්ලම් කිරීම සතුටක් නමුත් කේතය ලියා ඇති ආකාරය සමඟ සිදුවන්නේ කුමක්ද යන්න සැබවින්ම තේරුම් ගැනීමට ඔබට විවිධ අදහස් හෝ සංකල්ප සමඟ වැඩ කළ යුතුය. ඉතින් දැන් ඔබට බැලීමට බොහෝ කොන්දේසි තිබේ.
සිංගල්ටන්, පංතිය, මොඩියුලය, ස්වයං, වස්තුව සහ අයිජන් ක්ලාස් ගෙන එන ලද නමුත් රූබි වස්තු ආකෘති ඒ ආකාරයෙන් නම් නොකරයි. එය මෙටාක්ලාස් වැනි ය. රිචඩ් හෝ __ ඇයි ඔබට මෙහි අදහස පෙන්වන්නේ. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html තවද ඔබට පහරක් එල්ල වුවහොත් සෙවීමේදී රූබි වස්තු ආකෘතිය බැලීමට උත්සාහ කරන්න. යූ ටියුබ් හි මා දන්නා වීඩියෝ දෙකක් ඩේව් තෝමස් සහ පීටර් කූපර් ය. ඔවුන් එම සංකල්පය ද පැහැදිලි කිරීමට උත්සාහ කරති. එය ලබා ගැනීමට ඩේව්ට බොහෝ කාලයක් ගත විය, එබැවින් කරදර නොවන්න. මම තවමත් ඒ පිළිබඳව කටයුතු කරමින් සිටිමි. වෙන ඇයි මම මෙහෙට ආවේ? ඔබගේ ප්රශ්නයට ස්තූතියි. සම්මත පුස්තකාලය දෙස බලන්න. එය FYI ලෙස සිංගල්ටන් මොඩියුලයක් ඇත.
මේක ගොඩක් හොඳයි. https://www.youtube.com/watch?v=i4uiyWA8eFk