面向java开发人员的Ruby类定义解释

面向java开发人员的Ruby类定义解释,java,ruby,oop,Java,Ruby,Oop,我是一名java开发人员,很难理解这段Ruby代码,有人能用java术语解释一下这段代码吗?我能理解方法部分(defs),但属于部分让我困惑 module Test class Signature < Base belongs_to :recipient, :class_name => 'Test::UserInformation' belongs_to :sd_file, :class_name => 'Test::TransportFile',

我是一名java开发人员,很难理解这段Ruby代码,有人能用java术语解释一下这段代码吗?我能理解方法部分(defs),但属于部分让我困惑

module Test

  class Signature < Base
    belongs_to :recipient, :class_name => 'Test::UserInformation'
    belongs_to :sd_file, :class_name => 'Test::TransportFile',
                                         :foreign_key => 'reference_id'

    def sd_status
      sd_file.nil? ? nil : sd_file.Status
    end

    def sd_sent_on
      sd_file.nil? ? nil : sd_file.sent
    end

    def sd_received_on
      sd_file.nil? ? nil : sd_file.received
    end

    def self.find_information(options={})
      unless (start_date = options.delete(:start_date)).blank? ||
               (end_date   = options.delete(:end_date)).blank?
          date_conditions = ' AND '                           +
                            '(requested_at > ?) AND ' +
                            '(requested_at < ?)'            
      end
模块测试
类签名<基
属于收件人:class\u name=>'Test::UserInformation'
属于:sd\u文件,:class\u name=>“Test::TransportFile”,
:外键=>'reference\u id'
def sd_状态
sd_file.nil?nil:sd_file.Status
结束
def sd_已发送到
sd_file.nil?无:sd_file.sent
结束
def sd_在上收到
sd_file.nil?nil:sd_file.received
结束
def self.find_信息(选项={})
除非(开始日期=选项。删除(:开始日期))。空白||
(结束日期=选项。删除(:结束日期))。是否为空?
日期\条件='和'+
“(请求地址>?)和”+
"(请电)"
结束

属于
可能看起来像是一段非常神奇的ruby代码,它使用SQL表关联将您的模型连接到另一个模型

但它所做的只是接收一些散列参数,创建一系列动态方法

让我们拆开

belongs_to :sd_file, class_name: 'Test::TransportFile', foreign_key: 'reference_id'
属于
——一种建立关联的方法

sd\u文件
-将使用什么方法访问它:

  • Test::Signature.first.sd\u文件
class\u name
-指定加载哪个ruby类的选项
sd_文件
将指向
Test::TransportFile
。通常,如果一切都符合约定,则由
rails
自动完成。但您可以手动指定


外键
-将两条记录绑定在一起的表中的键。这要么在
Test::TransportFile
中,要么在
Test::Signature
中(我记不得了)。它将与另一个表中的
id
相关联。

属于
似乎是一段非常神奇的ruby代码,它使用SQL表关联将您的模型连接到另一个模型

但它所做的只是接收一些散列参数,创建一系列动态方法

让我们拆开

belongs_to :sd_file, class_name: 'Test::TransportFile', foreign_key: 'reference_id'
属于
——一种建立关联的方法

sd\u文件
-将使用什么方法访问它:

  • Test::Signature.first.sd\u文件
class\u name
-指定加载哪个ruby类的选项
sd_文件
将指向
Test::TransportFile
。通常,如果一切都符合约定,则由
rails
自动完成。但您可以手动指定


外键
-将两条记录绑定在一起的表中的键。这要么在
Test::TransportFile
中,要么在
Test::Signature
中(我记不得了)。它将与另一个表中的
id
相关联。

这里的关键是要认识到(几乎)Ruby中的所有内容都是一个脚本,(几乎)Ruby中的所有内容都是一个消息发送(“Java语言中的虚拟方法调用”),以及(几乎)Ruby中的所有内容都是一个对象

在Java中,唯一的可执行代码是在方法定义内部。其他一切都只是声明,即编译器创建某些编译器内部数据结构的指令。类声明不是在运行时执行的,而是在编译时由编译器进行解释,然后编译器生成相应的类结构、方法、字段等

在Ruby中不是这样。文件的内容只是一个自上而下执行的脚本。这就是为什么你可以,例如,拥有这样的东西:

if OS.windows?
  class Foo
  end
else
  class Bar
  end
end
if OS.windows?
  def foo
  end
else
  def bar
  end
end
class Foo < if rand < 0.5 then String else Array end
end
# Yes, I am aware that this makes zero sense. Here is a more sensible example:

class Point < Struct.new(:x, :y)
end
# `Struct` is a class whose `::new` method returns a class

class Search < R '/search'
end
# This is an example from the Camping web microframework:
# `Search` is a controller which is bound to the URI route `/search`
class Class
  def new(*args, &block)
    new_obj = allocate
    new_obj.initialize(*args, &block)
    return new_obj
  end
end
类似地,模块或类定义的主体只是一个脚本,它允许您拥有如下内容:

if OS.windows?
  class Foo
  end
else
  class Bar
  end
end
if OS.windows?
  def foo
  end
else
  def bar
  end
end
class Foo < if rand < 0.5 then String else Array end
end
# Yes, I am aware that this makes zero sense. Here is a more sensible example:

class Point < Struct.new(:x, :y)
end
# `Struct` is a class whose `::new` method returns a class

class Search < R '/search'
end
# This is an example from the Camping web microframework:
# `Search` is a controller which is bound to the URI route `/search`
class Class
  def new(*args, &block)
    new_obj = allocate
    new_obj.initialize(*args, &block)
    return new_obj
  end
end
因此,正如您所看到的,实际上几乎所有内容都是一个脚本,特别是类定义的主体只是一个从上到下执行的脚本,就像其他任何脚本一样

顺便说一下,由于类定义是在运行时动态执行的,而不是由编译器静态解释的,因此类定义中的超类定义也是如此:事实上,它只是一个任意的Ruby表达式,返回的对象是的实例,不必是静态常量类,也就是说,你可以这样写:

if OS.windows?
  class Foo
  end
else
  class Bar
  end
end
if OS.windows?
  def foo
  end
else
  def bar
  end
end
class Foo < if rand < 0.5 then String else Array end
end
# Yes, I am aware that this makes zero sense. Here is a more sensible example:

class Point < Struct.new(:x, :y)
end
# `Struct` is a class whose `::new` method returns a class

class Search < R '/search'
end
# This is an example from the Camping web microframework:
# `Search` is a controller which is bound to the URI route `/search`
class Class
  def new(*args, &block)
    new_obj = allocate
    new_obj.initialize(*args, &block)
    return new_obj
  end
end
同样,是发送给
self
的消息,在本例中是
Foo
attr_reader
只生成一个属性读取器(Java语言中的“getter”)。它看起来有点像这样(如果您还没有完全掌握Ruby反射,请不要担心,您无论如何都应该能够理解):

顺便说一句:
def
不是消息发送,而是一个内置关键字。但是有一种相应的方法可以替代,您可以在上面看到:

事实上,Ruby甚至没有构造函数!只是一个“类方法”,它看起来很像:

if OS.windows?
  class Foo
  end
else
  class Bar
  end
end
if OS.windows?
  def foo
  end
else
  def bar
  end
end
class Foo < if rand < 0.5 then String else Array end
end
# Yes, I am aware that this makes zero sense. Here is a more sensible example:

class Point < Struct.new(:x, :y)
end
# `Struct` is a class whose `::new` method returns a class

class Search < R '/search'
end
# This is an example from the Camping web microframework:
# `Search` is a controller which is bound to the URI route `/search`
class Class
  def new(*args, &block)
    new_obj = allocate
    new_obj.initialize(*args, &block)
    return new_obj
  end
end
这里有一些微妙之处,比如默认情况下是
私有的
,因此实际上我们需要使用反射来规避访问限制,但这就是它的要点

哦,因为我刚才提到了:这也是一个方法,而不是一个被解释为编译器指令的关键字

总而言之,我们的立场是:类定义只是一段代码,方法定义只是执行的表达式。但由于类定义只是一段代码,其中可能包含任意代码,包括消息发送(“Java语言中的方法调用”)<代码>所属\u to只是向类本身发送消息(方法调用),即该方法是在类对象本身的继承链的某个位置定义的(不要与继承混淆