[转]Why I like Ruby #1: alias_method

Rails中方法覆盖实践
本文介绍了一种在Rails中覆盖ActiveRecord方法的具体实践方法。通过使用alias_method技术,作者实现了在保留原有方法行为的基础上,增加了去除输入文本中不必要字符的功能。

So you found yourself in the need to override a method but still count on it’s old behaviour?

No problem! Override it with your new code, call super and…. Uh oh!! Suddenly this turned into a problem… Let me give some more context.

I was testing Ferret (and the acts_as_ferret plugin) in a project to provide full text search capabilities to our models. One of the things the plugin does is to add a new method to ActiveRecord, called find_with_ferret. That way, every model can use it. Great!

So I thought that would make sense for me to remove all diatrictics from the input text before letting ferret do its job. You know, like removing umlauts and all that.

I could do that by overriding this method with code to remove the undesired chars and then call its older version to finally do the search - something like calling super, but not quite. And I didn’t want my models to inherit from anything else than ActiveRecord::Base. That wouldn’t make any sense.

alias_method to the rescue!

You know that to redefine a method in an existing class you can open it up and rewrite it. But since you don’t wanna loose the behaviour provided by the original method, this is how you can achieve this:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> module ActiveRecord
  
class  Base
    alias_method :find_with_ferret_original, :find_with_ferret
 
    def find_with_ferret(q, options 
=  {}, find_options  =  {})
      remove_diatrictics
! (q)
      find_with_ferret_original(q, options, find_options)
    end
  end
end

And you’re good to go. On line 3 you’re just giving the original method an alias, making a copy of it.

Then you redefine it the way you like and on line 6 you call the old version to make sure u still got the same behaviour.
Now all my models can benefit of this change without requiring them to call another method nor inherit from another class.

Cool, huh? :)<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->

潮汐研究作为海洋科学的关键分支,融合了物理海洋学、地理信息系统及水利工程等多领域知识。TMD2.05.zip是一套基于MATLAB环境开发的潮汐专用分析工具集,为科研人员与工程实践者提供系统化的潮汐建模与计算支持。该工具箱通过模块化设计实现了两大核心功能: 在交互界面设计方面,工具箱构建了图形化操作环境,有效降低了非专业用户的操作门槛。通过预设参数输入模块(涵盖地理坐标、时间序列、测站数据等),用户可自主配置模型运行条件。界面集成数据加载、参数调整、可视化呈现及流程控制等标准化组件,将复杂的数值运算过程化为可交互的操作流程。 在潮汐预测模块中,工具箱整合了谐波分解法与潮流要素解析法等数学模型。这些算法能够解构潮汐观测数据,识别关键影响要素(包括K1、O1、M2等核心分潮),并生成不同时间尺度的潮汐预报。基于这些模型,研究者可精准推算特定海域的潮位变化周期与振幅特征,为海洋工程建设、港湾规划设计及海洋生态研究提供定量依据。 该工具集在实践中的应用方向包括: - **潮汐动力解析**:通过多站点观测数据比对,揭示区域主导潮汐成分的时空分布规律 - **数值模型构建**:基于历史观测序列建立潮汐动力学模型,实现潮汐现象的数字化重构与预测 - **工程影响量化**:在海岸开发项目中评估人工构筑物对自然潮汐节律的扰动效应 - **极端事件模拟**:建立风暴潮与天文潮耦合模型,提升海洋灾害预警的时空精度 工具箱以"TMD"为主程序包,内含完整的函数库与示例脚本。用户部署后可通过MATLAB平台调用相关模块,参照技术文档完成全流程操作。这套工具集将专业计算能力与人性化操作界面有机结合,形成了从数据输入到成果输出的完整研究链条,显著提升了潮汐研究的工程适用性与科研效率。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
""" Python面向对象编程详解 采用总分总结构:总体介绍 → 分层详解(封装/继承/多态) → 总结回顾 每个概念包含: 1. What(是什么):基础概念解释 2. Why(为什么用):使用场景和价值 3. How(如何用):代码实现基础写法 4. 示例:至少两个实际应用代码例子 """ ### 总体介绍:面向对象编程(OOP) ### &#39;&#39;&#39; OOP是什么:将数据和操作数据的方法组合成"对象"的编程范式 为什么用OOP: 1. 提高代码复用性(减少重复代码) 2. 增强代码可维护性(模块化结构) 3. 模拟现实世界关系(更直观建模) 三大核心特性:封装、继承、多态 &#39;&#39;&#39; ### 第一部分:封装(Encapsulation) ### &#39;&#39;&#39; 封装是什么:隐藏对象内部细节,仅暴露必要接口 为什么封装: 1. 防止外部直接修改内部数据(数据保护) 2. 简化使用复杂度(只需知道接口) 3. 便于修改内部实现(不影响外部调用) 基础写法: 1. 使用双下划线前缀(__)定义私有属性 2. 通过公有方法(get/set)访问和修改数据 3. 在方法中添加数据验证逻辑 &#39;&#39;&#39; # 基础写法示例: class BasicEncapsulation: def __init__(self, value): self.__private_value = value # 私有属性 def get_value(self): return self.__private_value # 公有访问方法 def set_value(self, new_value): if new_value > 0: # 验证逻辑 self.__private_value = new_value # 示例1:学生信息管理 class Student: def __init__(self, name, age): self.__name = name # 私有属性:姓名 self.__age = age # 私有属性:年龄 def get_info(self): """获取学生信息(封装数据访问)""" return f"{self.__name}, {self.__age}岁" def set_age(self, new_age): """修改年龄(封装数据修改)""" if 6 <= new_age <= 60: # 验证逻辑 self.__age = new_age return True return False # 示例2:银行账户管理 class BankAccount: def __init__(self, balance=0): self.__balance = balance # 私有属性:余额 def deposit(self, amount): """存款(封装存款操作)""" if amount > 0: self.__balance += amount return True return False def withdraw(self, amount): """取款(封装取款验证)""" if 0 < amount <= self.__balance: self.__balance -= amount return amount return 0 def get_balance(self): """查询余额(封装数据访问)""" return self.__balance ### 第二部分:继承(Inheritance) ### &#39;&#39;&#39; 继承是什么:子类自动获得父类属性和方法的能力 为什么继承: 1. 代码复用(避免重复编写相同功能) 2. 扩展功能(子类可添加新特性) 3. 层次化组织结构(建立类关系) 基础写法: 1. 声明继承关系:class ChildClass(ParentClass) 2. 使用super()调用父类方法 3. 添加子类特有属性和方法 &#39;&#39;&#39; # 基础写法示例: class Parent: def __init__(self, value): self.value = value class Child(Parent): # 继承Parent def __init__(self, value, extra): super().__init__(value) # 调用父类构造 self.extra = extra # 子类特有属性 # 示例1:交通工具体系 class Vehicle: # 父类 def __init__(self, brand, max_speed): self.brand = brand self.max_speed = max_speed def info(self): return f"{self.brand}, 最高时速:{self.max_speed}km/h" class Car(Vehicle): # 继承Vehicle def __init__(self, brand, max_speed, fuel_type): super().__init__(brand, max_speed) # 调用父类构造 self.fuel_type = fuel_type # 子类特有属性 def refuel(self): # 子类特有方法 print(f"正在加{self.fuel_type}...") # 示例2:动物分类体系 class Animal: def __init__(self, name): self.name = name def speak(self): print("动物发声") class Mammal(Animal): # 继承Animal def feed_milk(self): # 子类扩展方法 print(f"{self.name}正在哺乳幼崽") class Dog(Mammal): # 继承Mammal def speak(self): # 方法重写 print(f"{self.name}汪汪叫!") ### 第三部分:多态(Polymorphism) ### &#39;&#39;&#39; 多态是什么:不同对象对相同方法调用产生不同行为 为什么多态: 1. 接口统一(不同对象相同接口) 2. 增加灵活性(无需知道具体类型) 3. 易于扩展(新增子类不影响代码) 基础写法: 1. 方法重写:子类重新定义父类方法 2. 鸭子类型:不同类实现相同方法名 3. 接口统一:通过基类引用调用方法 &#39;&#39;&#39; # 基础写法示例: class Base: def action(self): pass class SubA(Base): def action(self): # 方法重写 print("A的动作") class SubB(Base): def action(self): # 方法重写 print("B的动作") # 示例1:图形面积计算 class Shape: def area(self): # 统一接口 pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): # 方法重写实现多态 return 3.14 * self.radius ** 2 class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): # 方法重写实现多态 return self.width * self.height # 示例2:日志记录器(鸭子类型) class FileLogger: def log(self, message): # 统一方法名 print(f"写入文件: {message}") class DatabaseLogger: def log(self, message): # 统一方法名(未继承) print(f"存入数据库: {message}") ### 总结回顾:综合应用 ### if __name__ == "__main__": print("=== 封装示例 ===") stu = Student("张三", 18) print(stu.get_info()) stu.set_age(20) print("\n=== 继承示例 ===") my_car = Car("丰田", 180, "汽油") print(my_car.info()) my_car.refuel() print("\n=== 多态示例 ===") shapes = [Circle(5), Rectangle(4, 6)] for s in shapes: print(f"图形面积: {s.area()}") # 相同接口不同实现 loggers = [FileLogger(), DatabaseLogger()] for logger in loggers: logger.log("系统启动") # 不同对象相同接口 print("\n=== OOP三大特性总结 ===") print("封装:隐藏细节暴露接口 (Student/BankAccount)") print("继承:父子类层级关系 (Vehicle/Car, Animal/Dog)") print("多态:相同接口不同实现 (Shape面积计算,Logger日志记录)") # ================ 五、总结回顾 ================ # 面向对象编程三大核心特性: # 1. 封装:隐藏实现细节(Student/BankAccount) # 2. 继承:父子类层级关系(Vehicle/Car,Animal/Dog) # 3. 多态:相同接口不同实现(Shape面积计算,Logger日志记录) # 基础写法格式说明: # 定义一个类的标准格式如下: # class 类名: # def __init__(self, 参数1, 参数2, ...): # self.属性1 = 参数1 # self.属性2 = 参数2 # def 方法名(self, 参数列表): # 方法体 # 创建对象: # 对象名 = 类名(参数列表) # 调用方法: # 对象名.方法名(参数列表) # OOP优势总结: # - 更易维护:结构清晰,修改一处影响全局 # - 更易扩展:通过继承轻松扩展功能 # - 更贴近现实:用类建模现实世界实体 # - 更灵活:通过多态支持统一接口不同行为 # ================== 结束 == 再加一些解释例如为什么用__init__在类里面 这个是必须的吗,放在一个py文件中
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值