Techioz Blog

Ruby クラスの一部のメソッドはデフォルトでプライベートになっているように見えますか?たとえそれらがクラス内の通常のメソッドであっても[クローズド]

概要

class ProcessTrip < MetroCardClassMethods
attr_accessor :travel_history, :station, :destination 

def initialize  
   
end    
def update_balace_aumount(balance_details,trip_to,trip_complete)
      effective_tarif = trip_complete ? passenger_tarif_for(_passenger_type) / 2 : passenger_tarif_for(_passenger_type)
      trip_to['discount']= effective_tarif if trip_complete
      trip_to['discount']= 0 if !trip_complete
     if   balance_details["balance"].to_i < effective_tarif
      effective_trip_cost = effective_tarif  - balance_details["balance"].to_i
      trip_to["trip_cost"] +=  effective_trip_cost*0.02
      balance_details["balance"] = 0;
     else
      balance_details["balance"] =  balance_details["balance"].to_i - effective_tarif
     end      
    end 
end

def total_amount_collected ()
  @@vertex.each do |metro_id, travel_history| 
    result = find_amount_collected_for_metrocard(self.class.card_list[metro_id], travel_history)     
    result.each do |key,value| 
      self.class.collection[key]["cost"]+=value["trip_cost"];
      self.class.collection[key]["discount"]+=value["discount"];   
      self.class.collection[key]["passengers"]+=value["passenger"];     
    end
   
  end
  return @@collection
end

def find_amount_collected_for_metrocard(balance_details, trip_info)    
  trip_from={}
  trip_info.each do |station, destination| 
    @station = station             
    if _is_return_journey(trip_from)    
      process_trip_segment(trip_from,_destination,_station)   
      trip_from[_station]["trip_cost"] = passenger_tarif_for(_passenger_type) * 0.5    
      update_balace_aumount(balance_details, trip_from[_station], true); 
    
    else               
      process_trip_segment(trip_from,_station,_station)       
      trip_from[_station]["trip_cost"] = (trip_from[_station]["trip_cost"] || 0) + passenger_tarif_for(_passenger_type)          
      update_balace_aumount(balance_details, trip_from[_station], false);  

    end           
  end    

return  trip_from

end 

ProcessTrip クラスのインスタンスから total_amount_collected を呼び出そうとしていますが、メソッドが通常のメソッドであり、private キーワードの下に置いていないにもかかわらず、プライベート メソッドであるというエラーが表示されます。

trip.total_amount_collected
NoMethodError: private method `total_amount_collected' called for #<ProcessTrip:0x0000000110e33da0>
from (pry):3:in `get_total_collection'

次のメソッドからクラスを呼び出しています

def get_total_collection
  trip =  ProcessTrip.new
  trip.total_amount_collected
  sort_passengers(total_collection); 
  print_summary(total_collection) if @print_summary
end  

さらに、ProcessTrip クラスによって拡張されたスーパークラスがあります

class MetroCardClassMethods
  @@card_list = []
  @@vertex = {};
  @@collection ={"CENTRAL"=>{"cost"=>0,"discount"=>0,"passengers"=>[]},"AIRPORT"=>{"cost"=>0,"discount"=>0,"passengers"=>[]}}
  @@station_from = {"CENTRAL"=>"AIRPORT","AIRPORT"=>"CENTRAL"}
  @@station = []

  def initialize(item)
    @travel_history =  {}  
    @metro_id = item["metro_id"] 
    @station = item["station"]
    @passenger_type = item["passenger_type"] 
    @destination = @@station_from[@station] 
  end

  class << self   
   
    def card_list=(card_list)
      @@card_list=card_list
    end 
    def card_list
      @@card_list
    end  
    def collection
      @@collection
    end  

    def station_from
      @@station_from
    end  
    def vertex
      @@vertex
    end  
  end  
 
end

total_amount_collected が private として扱われるのに対し、 update_balace_aumount は public メソッドとして扱われる理由を誰か説明できますか?

解決策

def/end のマッチングがオフになっています。 total_amount_collected の前の最後の端は、ProcessTrip クラスを閉じています。次に、total_amount_collected メソッドを完全にクラスの外で定義します。短い例を次に示します。

class MyClass
  def some_method
  end
end
def some_other_method
end

これを IRB コンソールに貼り付けて呼び出した場合:

MyClass.new.some_other_method

some_other_method が MyClass の新しいパブリック インスタンス メソッドとしてではなく、Object クラスの新しいプライベート メソッドとして定義されているため、プライベート メソッド例外が発生します。