除了动态类型,是什么让Ruby“比Java更灵活”?

时间:2009-04-05 06:03:01

标签: java ruby duck-typing dynamic-languages

我几乎一直在使用Java,因为它刚出现,但在过去的五年中,它已经被烧毁了,即使是最简单的事情也变得多么复杂。我开始在我的精神科医生的推荐下学习Ruby,呃,我的意思是我的同事(年轻,冷静的同事 - 他们使用Macs!)。无论如何,他们不断重复的一件事是,Ruby是一种“灵活”的语言,而不是像Java那样的老式,更加拙劣的语言,但我真的不知道这意味着什么。有人能解释是什么让一种语言比另一种语言“更灵活”?请。我对动态类型有所了解,可以看出这对简洁有什么好处。 Ruby语法很漂亮。还有什么?动态打字是主要原因吗?

7 个答案:

答案 0 :(得分:6)

这也是因为它是无类别的(在Java意义上)但完全面向对象(属性模式)所以你可以调用任何方法,即使没有定义,你仍然有机会动态响应调用,示例创建必要的方法。 Ruby也不需要编译,因此您可以根据需要轻松更新正在运行的应用程序。此外,对象可以在其生命周期中通过mixin突然从其他类/对象继承,因此它是另一个灵活点。无论如何我同意孩子们这种语言称为Ruby,它实际上和Java一样长,在许多方面都非常灵活和优秀,但我仍然无法同意它的美丽(语法方面),C是更美丽的恕我直言(我是支架的傻瓜),但美是主观的,红宝石的其他品质是客观的

答案 1 :(得分:6)

动态类型并未接近覆盖它。举一个很好的例子,Ruby在许多情况下使元编程变得容易。在Java中,元编程要么是痛苦的要么是不可能的。

例如,采用Ruby通常的方式声明属性:

class SoftDrink
  attr_accessor :name, :sugar_content
end
# Now we can do...
can = SoftDrink.new
can.name = 'Coke' # Not a direct ivar access — calls can.name=('Coke')
can.sugar_content = 9001 # Ditto

这不是一些特殊的语言语法 - 它是Module类的一个方法,而且很容易实现。以下是attr_accessor的示例实现:

class Module
  def attr_accessor(*symbols)
    symbols.each do |symbol|
      define_method(symbol) {instance_variable_get "@#{symbol}"}
      define_method("#{symbol}=") {|val| instance_varible_set("@#{symbol}", val)}
    end
  end
end

这种功能可以让您在表达程序时获得很多灵活性。

许多看起来像语言功能(以及大多数语言中的语言功能)都只是Ruby中的常用方法。再举一个例子,这里我们动态加载其名称存储在数组中的依赖项:

dependencies = %w(yaml haml hpricot sinatra couchfoo)
block_list %w(couchfoo) # Wait, we don't really want CouchDB!
dependencies.each {|mod| require mod unless block_list.include? mod}

答案 2 :(得分:5)

块,闭包,很多东西。我肯定会在早上出现一些更好的答案,但是举一个例子,这是我十分钟前写的一些代码 - 我有一系列的scheduled_collections,其中一些已经发生,其他已经废弃,取消等等我想返回一个只有待处理数组的数组。我不确定等效的Java是什么,但我想这不是这种单行方法:

def get_all_pending
  scheduled_collections.select{ |sc| sc.is_pending? }
end

同样事情的一个更简单的例子是:

[0,1,2,3].select{|x| x > 1}

哪个会产生[2,3]

答案 3 :(得分:4)

我喜欢的东西

  • 减少代码来解决问题
  • 传递代码块(Proc,lambdas)很有趣,可能会导致代码更加模糊。例如[1, 2, 3].each{|x| puts "Next element #{x}"}
  • 具有PERL的脚本根。非常适合切割n个骰子常规的东西,比如使用regexps解析文件等。所有
  • 核心数据结构类API(如Hash和Array)已经很好地完成了。
  • 元编程(由于其动态特性) - 创建自定义DSL的能力(例如Rails可以称为用Ruby编写的WebApps的DSL)
  • 几乎可以为任何事物生成宝石的社区。

答案 4 :(得分:2)

混入。改变Ruby类以添加新功能非常简单。

答案 5 :(得分:2)

Duck typing 指的是当类型被它们实现的方法视为等效时,而不是基于它们声明的类型。举一个具体的例子,Ruby中的许多方法都采用类似IO的对象来操作流。这意味着对象必须实现足够的功能才能作为IO类型对象传递(它必须听起来像鸭子一样)。

最后,这意味着您必须编写比Java更少的代码来执行相同的操作。但是,关于动态语言的一切都不是很好。您或多或少会放弃Java(以及其他强/静态类型语言)为您提供的所有编译时类型检查。 Ruby根本不知道你是否要将错误的对象传递给方法;这会给你一个运行时错误。此外,在实际调用代码之前,它不会给您一个运行时错误。

答案 6 :(得分:2)

只是为了笑,这是语言灵活性的一个相当令人讨厌的例子:

class Fixnum
  def +(other)
    self - other
  end
end

puts 5 + 3
# => 2