Pertanyaan Proteksi dan metode pribadi di Rails


Metode visibilitas di Ruby (metode publik, dilindungi, dan pribadi) telah dijelaskan dengan baik di tempat-tempat seperti posting blog ini. Namun di Ruby on Rails tampaknya sedikit berbeda dari yang ada pada aplikasi Ruby biasa karena cara kerangka kerja ini diatur. Jadi, dalam model Rails, pengontrol, penolong, tes, dll., Kapan / tidak tepat untuk menggunakan metode yang dilindungi atau pribadi?

Edit: Terima kasih atas jawaban sejauh ini. Saya memahami konsep yang dilindungi dan bersifat pribadi di Ruby, tetapi saya mencari lebih banyak penjelasan tentang cara tipikal jenis visibilitas yang digunakan dalam konteks berbagai bagian aplikasi Rails (model, pengontrol, pembantu, pengujian) . Misalnya, metode pengendali publik adalah metode tindakan, metode yang dilindungi dalam pengontrol aplikasi digunakan untuk "metode pembantu" yang perlu diakses oleh beberapa pengontrol, dll.


76
2017-12-20 23:45


asal


Jawaban:


Untuk model, idenya adalah bahwa metode publik adalah antarmuka publik kelas. Metode publik dimaksudkan untuk digunakan oleh objek lain, sementara metode yang dilindungi / pribadi harus disembunyikan dari luar.

Ini adalah praktik yang sama seperti bahasa berorientasi objek lainnya.

Untuk pengendali dan tes, lakukan saja sesukamu. Baik controller maupun kelas tes hanya instantiated dan dipanggil oleh kerangka kerja (ya, saya tahu Anda dapat secara teoritis mendapatkan pengontrol dari tampilan, tetapi jika Anda melakukan itu, ada sesuatu yang aneh). Karena tidak ada yang akan menciptakan hal-hal itu secara langsung, tidak ada yang perlu "dilindungi".

Adendum / Koreksi: Untuk pengendali, Anda harus menandai metode "penolong" sebagai terlindung pribadi, dan hanya tindakannya sendiri yang harus bersifat publik. Kerangka kerja tidak akan pernah mengarahkan panggilan HTTP yang masuk ke tindakan / metode yang tidak umum, sehingga metode pembantu Anda harus dilindungi dengan cara itu.

Untuk pembantu tidak akan ada bedanya jika suatu metode dilindungi atau pribadi, karena mereka selalu disebut "langsung".

Anda dapat menandai hal-hal yang dilindungi dalam semua kasus itu jika itu membuat semuanya lebih mudah bagi Anda untuk mengerti, tentu saja.


97
2018-01-05 17:47



Anda menggunakan metode pribadi jika Anda mau tidak ada yang lain tapi self untuk menggunakan metode. Anda menggunakan metode terlindungi jika Anda menginginkan sesuatu saja self and is_a?(self) s dapat menelepon.

Penggunaan yang baik dari yang dilindungi mungkin jika Anda memiliki metode inisialisasi "virtual".

class Base
    def initialize()
        set_defaults()
        #other stuff
    end

    protected
    def set_defaults()
        # defaults for this type
        @foo = 7
        calculate_and_set_baz()
    end

    private
    def calculate_and_set_baz()
        @baz = "Something that only base classes have like a file handle or resource"
    end
end

class Derived < Base
    protected
    def set_defaults()
        @foo = 13
    end
end

@foo akan memiliki nilai yang berbeda. dan contoh Berasal tidak akan memiliki @ baz

Memperbarui: Sejak saya menulis ini, beberapa hal telah berubah di Ruby 2.0+ Aaron Patterson memiliki penulisan yang sangat baik http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html


60
2017-12-21 00:08



Perbedaan antara dilindungi dan   pribadi itu halus. Jika suatu metode   dilindungi, itu bisa dipanggil oleh apapun   contoh kelas mendefinisikan atau nya   subclass. Jika suatu metode bersifat pribadi, itu   bisa disebut hanya dalam konteks   dari objek panggilan --- itu tidak pernah   mungkin untuk mengakses objek lain   Instansi swasta instan secara langsung,   bahkan jika objeknya sama   kelas sebagai penelepon. Untuk dilindungi   metode, mereka dapat diakses dari   objek dari kelas yang sama (atau   anak-anak).

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility


9
2017-12-20 23:54



Anda tampaknya memiliki ide bagus tentang semantik visibilitas kelas (publik / dilindungi / pribadi) sebagaimana diterapkan pada metode. Yang bisa saya tawarkan adalah garis cepat dari cara saya menerapkannya di aplikasi Rails saya.

Saya menerapkan metode yang dilindungi dalam pengontrol aplikasi dasar sehingga mereka dapat dipanggil oleh pengontrol melalui filter (mis. Before_filter: method_foo). Dengan cara yang sama, saya mendefinisikan metode yang dilindungi untuk model yang ingin saya gunakan semuanya dalam model dasar yang mereka semua mewarisi darinya.


3
2018-01-04 07:09



Meskipun tindakan perlu menjadi metode umum dari pengontrol, tidak semua metode publik adalah tindakan yang perlu dilakukan. Kamu dapat memakai hide_action jika Anda menggunakan rute penangkap-semua seperti /:controller/:action/:id atau jika dinonaktifkan (default di Rails 3) maka hanya metode dengan rute eksplisit yang akan dipanggil.

Ini dapat bermanfaat jika Anda meneruskan instance controller ke beberapa pustaka lain seperti mesin template Liquid karena Anda dapat menyediakan antarmuka publik daripada harus menggunakan kirim dalam filter dan tag Liquid Anda.


2
2018-01-07 11:36