według książki z której się ucze powinno zwrócić “4” a zwraca to:
*NoMethodError: private method dupa' called for 2.0:Float from (irb):71 from /home/dominik/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/railties-4.0.0.beta1/lib/rails/commands/console.rb:88:instart’
from /home/dominik/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/railties-4.0.0.beta1/lib/rails/commands/console.rb:9:in start' from /home/dominik/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/railties-4.0.0.beta1/lib/rails/commands.rb:64:in<top (required)>’
from bin/rails:4:in require'* from bin/rails:4:in’
może mi ktoś wytłumaczyć dlaczego? jestem zielonek i szukając w google i tu nie znalazłem odpowiedzi
Pozdrawiam.
P.S. z racji tego że jest to mój pierwszy post tutaj jeżeli nieprzestrzegam nim jakichś zasad proszę o zwrócenie uwagi ;]
rozumiem a dlaczego książka o tym nie mówi? dodam że książka z której się uczę to: “ruby, szybki start” Larry Ullman, i jak do tej pory jeszcze nie miałem nic z klasami i “on” tutaj wrzucając przykłady nie ma takiego probelmu. czyżby coś się zminiło w Ruby2.0? bo taki mam a książka jest na Rubym1.9.
Dopisane jest w ksiązce: Metody zdefiniowane poza wszelkimi klasami takie jak wszystkie, które zostały przeddstawione w tym rozdziale, stają się częścią klasy Ruby o nazwieObject. Z tego powodu można jes stosować podobnie jak funkcje globalne do dowolnego obiektu.
metoda dodana w IRB poza klasą jest dostępna wszędzie, dlatego definiując add możesz je wywołać na dowolnej klasie (w rzeczywistości rozszerzasz Object z którego prawie wszystko dziedziczy.)
Problem w tym że te metody są prywatne dlatego nie możesz ich wykonywać. Teoretycznie IRB powinno robić je publicznymi (według internetów), nie wiem dlaczego tak się nie dzieje (możliwe że w którejś wersji to zmienili).
żeby to obejść możesz zadeklarować metodę explicite publicznie, np.
irb(main):001:0> public def add(x); self + x; end
=> Object
irb(main):002:0> 3.add 2
=> 5
rozumiem, czyli ten problem dotyczy tylko IRB? reszta będzie ok? jeżeli tak i nikt nie ma pomyslu dlaczego to jest private a nie public no to chyba nie ma co drążyć ;]
Pozwolę sobie na kilka słów wyjaśniających. Każda metoda zdefiniowana w sposób globalny, niezależnie czy mówimy o irbie czy po prostu pliku, który zostanie załadowany przez ruby, będzie należeć do klasy Object i będzie metodą prywatną.
Jako, że uczysz się dopiero języka dobrze jest tego typu teorie umieć poprzeć eksperymentem.
> def foo
| puts "foo"
| end
:foo
> method(:foo).owner
Object
> foo
foo
nil
> self.foo
NoMethodError: private method `foo' called for main:Object
from (irb):6
from /Users/radarek/.rbenv/versions/2.2.0/bin/irb:11:in `<main>'
(dlaczego samo “foo” zadziałało, a dlaczego już “self.foo” nie, dowiesz się czytając o poziomach dostępu do metod).
Dlaczego te metody są prywatne a nie publiczne? Przede wszystkim raczej nie chcielibyśmy by deklaracja globalnej metody rozszerzała interfejs publiczny każdej klasy (obiekt.puts "wtf"), prawda? O takich globalnych metodach myślimy raczej jak o funkcjach. Zatem gdy piszę “puts”, które wywołam w klasie “Foo”, raczej nie myślę “wywołuję metodę prywatną na instancji klasy Foo” tylko “wywołuję funkcję puts”.
Co do różnicy między irb a rubym - wątpię by kiedykolwiek była taka. Jeśli była to prędzej kopę lat temu co świadczyłoby o tym, że książka jest przestarzała.
Co do Twojego przykładu to raczej bym się spodziewał, że faktycznie ta metoda jest zdefiniowana w którejś z klas reprezentujących liczby. Więc albo coś pokiełbasiłeś, ale autor tej książki nie wiedział o czym pisze ;).
W rubym 1.9.3 i wcześniejszych wersjach metody, które definiowałeś nie były prywatne i ten kod działał. Bodaj od wersji 2.0.0 już tak nie jest i ten sam kod nie zadziała.
Dokładnie To najbardziej interesowało Dominika. Odnośnie wykonywanie kodu to metody, które deklarujemy poza jakąkolwiek klasą mają modyfikator prywatny i nie możemy ich wywołać na rzecz innego obiektu. Niejawnie metoda ta jest wywoływana na rzecz obiektu ‘main’ (wywołaj puts self).
noo dokładnie mnie to interesowało. Bo książke mam z ruby 1.9 i zastanawiałem sie czy to po prostu się nie zmieniło w 2.0.
Noo jak narazie walcze z tym rubym, dużo jest jeszcze niejasności w tym ale idzie to do przodu niestety nie jest to jeszcze etap gdzie można aplikować do jakiejś pracy podejrzewam. A szkoda bo mi praca potrzebna ;D