Frage

Es ist schon eine Weile her, seit ich das letzte Mal Ruby-Programmierung haben - Blick auf jemand anderem Code, sehe ich die @ Sigill in einer Funktion ( nicht ein Verfahren - extern zu jeder Klassendefinition), die ich verstand Instanz Mitglieder scoped werden.

Das Modul ist der implizite self in Funktionen?

War es hilfreich?

Lösung

In einer Top-Level-Funktion (noch ein Verfahren wirklich), du bist in einem etwas seltsamen Ort: eine globale „main“ Raum (die Eingabeaufforderung angezeigt, wenn Sie irb ausführen oder versuchen, bei self innerhalb einer solchen Funktion suchen) aber auch diese Funktionen als private Methoden in der Object Klasse definiert ist.

$ cat foo
def foo
  p self
  p self.class
  puts 'foo'
end

foo
Object.foo

$ ruby foo
main
Object
foo
foo:8: private method `foo' called for Object:Class (NoMethodError)
$ 

Sie können rund um diese schleichen durch explizit diese Methoden public erklären, aber ich bin nicht sicher, ob ich das gefällt! Seltsamerweise, wenn Sie ein Top-Level-Methode innerhalb irb definieren, dann können Sie es über die Klassenmethode Object#foo aufrufen, ohne es öffentlich zu erklären.

Das ist also eine Art „impliziten Hauptnamensraum auf Object gehackt (aber pssst jemand nicht sagen)“. @foo innerhalb einer Funktion der obersten Ebene definiert ist, im Inneren Objekt, als einfaches altes Attribut zur Verfügung. Art. Wenn Ihr Top-Level-Methode @foo gesetzt und Sie es nennen, ohne Scoping dann ist es in der Eigen wie main Namespace deklariert, aber wenn Sie die Klassenmethode über Object rufen dann erscheint @foo innerhalb von Object.

Ein weiteres Beispiel:

public
def set_foo
  @foo = 'foo'
end

def get_foo
  @foo
end

def Object.get_foo_again
  @foo
end

set_foo
p get_foo
p Object.get_foo_again

Object.set_foo
p Object.get_foo_again

gibt

"foo"  # @foo set in main
nil    # @foo nil in Object  
"foo"  # @foo in Object

Die Umkehrung gilt auch.

Andere Tipps

Die Annahme, dass dies „eine Funktion, kein Verfahren“ ist falsch. All Ruby-Code erfolgt im Rahmen eines Objekts. Der „globale“ Kontext ist ein Objekt namens main (versuchen ruby -e "puts self", wenn Sie es nicht glauben). Methods in dem oberen Bereich definiert werden Instanzmethoden Object. Dies bedeutet, dass das Verfahren zur Verfügung stehen wird überall , mit self (und damit dem Zusammenhang, dass Instanzvariablen gehört), je nachdem, wo die Methode aufgerufen wird,

Ich denke, es Tive es zu einem Modul.

@ macht eine Variable eine Instanzvariable. Es klingt wie es ist kein Teil einer explizit deklarierten Klasse ist, so ist es in der Hauptsache zur Verfügung gehen, wie Chuck hingewiesen. Es ist einfacher, mit gutem Beispiel dargestellt:

$ irb
irb(main):001:0> @var = 1
=> 1
irb(main):002:0> class New
irb(main):003:1>   def test
irb(main):004:2>     puts @var
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> test = New.new
=> #<New:0xb7ccbc14>
irb(main):008:0> test.test
nil
=> nil
irb(main):009:0> def test2
irb(main):010:1>   puts @var
irb(main):011:1> end
=> nil
irb(main):012:0> test2
1
=> nil
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top